Memoria pfc, Metaproxy documentation
-
Upload
slok69 -
Category
Technology
-
view
1.267 -
download
5
description
Transcript of Memoria pfc, Metaproxy documentation
DeustoFacultad de Ingeniería Universidad de Deusto
Ingeniaritza Fakultatea Deustuko Unibertsitatea
Ingeniero en InformáticaInformatikako Ingeniaria
Proyecto fin de carreraKarrera amaierako proiektua
iii
Resumen
Actualmente, existe una problemática (principalmente en los móviles de última
generación) en lo referente a los datos que contienen las páginas web: muchas
aplicaciones tanto móviles como de escritorio, e incluso otras páginas web (como por
ejemplo, buscadores) requieren unos datos “extra” de las páginas web, para la
realización de una serie de funcionalidades específicas. A estos datos “extra” se les
denomina metadatos y en la actualidad, muchas veces estos datos no son visibles a
simple vista o no son presentados visualmente a los humanos de manera adecuada.
El objetivo de este proyecto es el de crear un servidor proxy que permita que
los metadatos (datos extra) de las páginas web convencionales puedan ser
visualizados de manera adecuada para los seres humanos mediante el uso de una de
las tecnologías de moda en los últimos tiempos: la Web Semántica.
El servidor proxy hará de intermediario entre el cliente que desea la página web
y el servidor que le proporciona dicha página web al cliente. Gracias al servidor proxy,
el cliente obtendrá una versión ligeramente modificada de la página web solicitada. El
servidor, aparte de obtener una copia de la página solicitada, extraerá de ella los
metadatos y los transformará en un formato adecuado para su posterior visualización
en formatos entendibles como XML o grafos. Es más, el servidor, también tendrá la
capacidad de insertar metadatos en las propias páginas si así se desea.
El manejo del servido proxy se realizará a través de un portal web
implementado mediante el framework de desarrollo web de código abierto Django, por
lo que el usuario del proxy únicamente deberá de disponer de un navegador web para
acceder a éste.
Para la configuración del servidor proxy se dispondrá de un panel de control al
cual sólo podrán acceder los administradores a través del portal mencionado en el
anterior párrafo. Mediante él, se podrán insertar datos en la base de datos, añadir
nuevas páginas al servidor para ser tratadas y hacer consultas especiales (SPARQL)
sobre los metadatos almacenados previamente extraídos de las páginas solicitadas.
Asimismo, también se podrá cambiar el comportamiento del servidor proxy, es decir, a
pesar de que por defecto el proxy esté configurado para la extracción/manejo de
metadatos, los usuarios podrán subir al servidor scripts en Python personalizados que
hagan que el servidor realice otras actividades como puede ser la traducción o la
modificación del aspecto de una página web o como se ha mencionado anteriormente,
la propia inserción de metadatos en páginas web tradicionales.
iv
Descriptores
Web semántica
Proxy
Páginas web
Interpretación de datos.
v
Índice
1. Introducción ______________________________________________________ 1
1.1 Acerca del proyecto ___________________________________________________ 1
1.2 Acerca de la documentación ____________________________________________ 1
2. Definición del proyecto _____________________________________________ 3
2.1 Objetivos ___________________________________________________________ 3
2.2 Alcance _____________________________________________________________ 4
2.2.1 Alcance del proyecto _______________________________________________________ 4
2.2.2 Alcance de la investigación __________________________________________________ 4
2.2.3 Alcance de la documentación ________________________________________________ 4
2.2.4 Alcance de la herramienta ___________________________________________________ 5
2.3 Producto final ________________________________________________________ 5
2.4 Descripción de la realización ____________________________________________ 6
2.4.1 Método de desarrollo: ______________________________________________________ 6
2.4.2 Tareas principales: _________________________________________________________ 7
2.5 Organización y equipo ________________________________________________ 10
2.6 Presupuesto ________________________________________________________ 12
2.7 Condiciones de ejecución _____________________________________________ 12
3. Conceptos básicos ________________________________________________ 15
3.1 Proxy ______________________________________________________________ 15
3.1.1 Tipos ___________________________________________________________________ 15
3.1.2 Funcionamiento __________________________________________________________ 17
3.2 Web Semántica _____________________________________________________ 17
3.2.1 Definición _______________________________________________________________ 17
3.2.2 Utilidades _______________________________________________________________ 17
3.2.3 Funcionamiento __________________________________________________________ 18
3.3 Ontologías _________________________________________________________ 20
3.4 SPARQL ____________________________________________________________ 21
3.5 Linked Data ________________________________________________________ 21
3.6 Expresiones regulares ________________________________________________ 22
3.7 GRDDL _____________________________________________________________ 26
3.7.1 Ejemplo con XHTML _______________________________________________________ 27
3.7.2 Microformatos ___________________________________________________________ 27
vi
4. Justificación _____________________________________________________ 29
4.1 Beneficios técnicos ___________________________________________________ 29
4.2 Beneficios económicos ________________________________________________ 29
5. Investigación en tecnologías _______________________________________ 31
5.1 Visión general _______________________________________________________ 31
5.2 Recursos principales __________________________________________________ 31
5.2.1 Python _________________________________________________________________ 31
5.2.2 Django _________________________________________________________________ 35
5.2.3 Django-Revproxy _________________________________________________________ 40
5.2.4 Redland ________________________________________________________________ 43
5.2.5 Git ____________________________________________________________________ 51
5.3 Recursos ___________________________________________________________ 57
5.3.1 Restkit _________________________________________________________________ 57
5.3.2 LXML __________________________________________________________________ 58
5.3.3 Pygments _______________________________________________________________ 59
5.3.4 Python Graph & Graphviz __________________________________________________ 59
5.3.5 Beautiful Soup ___________________________________________________________ 63
6. Desarrollo ______________________________________________________ 65
6.1 Estructura del proyecto _______________________________________________ 65
6.1.1 Portal Web (Django) ______________________________________________________ 65
6.1.2 Proxy __________________________________________________________________ 81
6.1.3 Scripts _________________________________________________________________ 84
6.2 API ________________________________________________________________ 98
6.2.1 ModifyBodyBase _________________________________________________________ 98
6.2.2 Utilidades ______________________________________________________________ 100
7. Usos alternativos _______________________________________________ 103
7.1 Traducción ________________________________________________________ 103
7.1.1 Google API _____________________________________________________________ 103
7.2 Discapacitados _____________________________________________________ 105
7.3 Analizador de código malicioso ________________________________________ 105
7.4 Guardar datos ______________________________________________________ 105
7.5 Notificaciones ______________________________________________________ 106
7.5.1 Redes sociales __________________________________________________________ 106
7.5.2 E-mails ________________________________________________________________ 106
7.5.3 SMS __________________________________________________________________ 107
7.6 Testeo de páginas web _______________________________________________ 107
7.6.1 Diseño ________________________________________________________________ 107
7.6.2 Actualizaciones _________________________________________________________ 107
vii
8. Conclusiones ___________________________________________________ 109
8.1 Objetivos alcanzados ________________________________________________ 109
8.2 Consideraciones ____________________________________________________ 109
8.3 Posibles mejoras futuras _____________________________________________ 110
9. Agradecimientos ________________________________________________ 113
10. Licencias _______________________________________________________ 115
10.1 Imágenes________________________________________________________ 115
10.2 Documentación __________________________________________________ 115
10.3 Proyecto ________________________________________________________ 120
10.4 Revproxy ________________________________________________________ 132
11. Glosario _______________________________________________________ 133
12. Bibliografía ____________________________________________________ 145
12.1 Proxys (Ver 3.1) __________________________________________________ 145
12.2 Web Semántica (Ver 3.2) ___________________________________________ 145
12.3 Ontologías (Ver 3.3) _______________________________________________ 145
12.4 SPARQL (Ver 3.4) _________________________________________________ 145
12.5 Linked Data (Ver 3.5) ______________________________________________ 146
12.6 Expresiones regulares (Ver 3.6) ______________________________________ 146
12.7 GRDDL (Ver 3.7) __________________________________________________ 146
12.8 Python (Ver 5.2.1) ________________________________________________ 146
12.9 Django (Ver 5.2.2)_________________________________________________ 146
12.10 Django revproxy (Ver 5.2.3) _________________________________________ 147
12.11 Redland (Ver 5.2.4) ________________________________________________ 147
12.12 Git (Ver 5.2.5) ____________________________________________________ 147
12.13 Restkit (Ver 5.3.1) _________________________________________________ 147
12.14 LXML (Ver 5.3.2) __________________________________________________ 147
12.15 Pygments (Ver 5.3.3) ______________________________________________ 147
12.16 Python graph (Ver 5.3.4) ___________________________________________ 147
12.17 Beautiful Soup (Ver 5.3.5) __________________________________________ 148
12.18 Desarrollo (Ver 6) _________________________________________________ 148
12.19 Usos alternativos (Ver 7) ___________________________________________ 148
12.20 Conclusiones (Ver 8) _______________________________________________ 148
viii
12.21 Licencias (Ver 10) _________________________________________________ 148
12.22 Manual de usuario (Ver 13) _________________________________________ 148
12.23 Glosario (Ver 11) __________________________________________________ 149
12.24 Otros ___________________________________________________________ 149
13. Manual de usuario ______________________________________________ 151
13.1 Instalación _______________________________________________________ 151
13.1.1 Requisitos primarios _____________________________________________________ 151
13.1.2 Requisitos _____________________________________________________________ 151
13.2 Entorno de producción _____________________________________________ 155
13.2.1 Requisitos _____________________________________________________________ 155
13.2.2 Se presupone ___________________________________________________________ 155
13.2.3 Configurar Nginx ________________________________________________________ 155
13.2.4 Añadir configuración de Django uWSGI ______________________________________ 156
13.2.5 Script para hacer deploy de aplicaciones Django_______________________________ 157
13.2.6 Script de ejecucucíon uWSGI ______________________________________________ 157
13.2.7 Configuración Django ____________________________________________________ 159
13.2.8 Crear base de datos para Django ___________________________________________ 159
13.2.9 Ejecución en modo producción ____________________________________________ 159
13.3 Uso ____________________________________________________________ 161
13.3.1 Página principal _________________________________________________________ 161
13.3.2 Sección administración de la página web ____________________________________ 162
13.3.3 Sección Administrador proxy ______________________________________________ 164
13.3.4 Ejemplos sobre el proyecto _______________________________________________ 176
Tabla de Ilustraciones
Ilustración 2-1: Tabla de tareas ------------------------------------------------------------------------------------------------- 8
Ilustración 2-2: Diagrama de Gantt -------------------------------------------------------------------------------------------- 9
Ilustración 2-3: Esquema organizativo -------------------------------------------------------------------------------------- 10
Ilustración 3-1: Ilustración de un forward proxy -------------------------------------------------------------------------- 15
Ilustración 3-2: Ilustración de un proxy abierto --------------------------------------------------------------------------- 16
Ilustración 3-3: Ilustración de un proxy inverso --------------------------------------------------------------------------- 16
Ilustración 3-4: Estructura de la web semántica-------------------------------------------------------------------------- 19
Ilustración 3-5: Ejemplo de ontología --------------------------------------------------------------------------------------- 20
Ilustración 3-6: Conjunto de datos interconectados entre sí que componen la "Nube de Linked Data" --- 22
Ilustración 5-1: Logo de Python ----------------------------------------------------------------------------------------------- 31
Ilustración 5-2: Logo Django --------------------------------------------------------------------------------------------------- 35
Ilustración 5-3: Flujo ------------------------------------------------------------------------------------------------------------- 37
Ilustración 5-4: Estructura de un proyecto en Django ------------------------------------------------------------------- 38
ix
Ilustración 5-5: Flujo de Django-Revproxy ---------------------------------------------------------------------------------- 41
Ilustración 5-6: Carpetas y archivos de Revproxy ------------------------------------------------------------------------- 43
Ilustración 5-7: Logo Git --------------------------------------------------------------------------------------------------------- 51
Ilustración 5-8: Estados de trabajo con Git --------------------------------------------------------------------------------- 54
Ilustración 5-9: Commits y branchs del proyecto visualizados en gitk----------------------------------------------- 55
Ilustración 5-10: Logo Github -------------------------------------------------------------------------------------------------- 55
Ilustración 5-11: Proyecto hospedado en Github ------------------------------------------------------------------------- 56
Ilustración 5-12: Branchs del proyecto en Github ------------------------------------------------------------------------- 57
Ilustración 5-13: Grafo creado con Graphviz ------------------------------------------------------------------------------- 61
Ilustración 6-1: Estructura del proyecto ------------------------------------------------------------------------------------- 65
Ilustración 6-2: Estructura de un paquete HTTP --------------------------------------------------------------------------- 83
Ilustración 6-3: Algunos argumentos de la cabecera de un paquete HTTP ---------------------------------------- 83
Ilustración 7-1: Clave de la API de Google -------------------------------------------------------------------------------- 104
Ilustración 7-2: Panel de control de API de Google --------------------------------------------------------------------- 104
Ilustración 13-1: Página principal ------------------------------------------------------------------------------------------- 161
Ilustración 13-2: Menú de la página principal --------------------------------------------------------------------------- 161
Ilustración 13-3: Páginas registradas en el proxy ----------------------------------------------------------------------- 162
Ilustración 13-4: Acceso al repositorio online con el código fuente ------------------------------------------------ 162
Ilustración 13-5: Login de la administración de la web ---------------------------------------------------------------- 162
Ilustración 13-6: Pantalla principal del panel de adminsitración de la web ------------------------------------- 163
Ilustración 13-7: Añadir nuevo usuarios ----------------------------------------------------------------------------------- 163
Ilustración 13-8: Lista de usuarios ------------------------------------------------------------------------------------------ 164
Ilustración 13-9: Zoom de la lista de usuarios --------------------------------------------------------------------------- 164
Ilustración 13-10: Menú de administración del proxy (Manager) -------------------------------------------------- 165
Ilustración 13-11: Login administrador proxy ---------------------------------------------------------------------------- 165
Ilustración 13-12: Iconos del menú del Manager ----------------------------------------------------------------------- 166
Ilustración 13-13: RDF Uploader -------------------------------------------------------------------------------------------- 166
Ilustración 13-14: Subir archivo RDF desde la máquina local -------------------------------------------------------- 167
Ilustración 13-15: Selección del archivo RDF local ---------------------------------------------------------------------- 167
Ilustración 13-16: Descargar archivo RDF--------------------------------------------------------------------------------- 167
Ilustración 13-17: Selección de la base de datos donde almacenar el archivo RDF ---------------------------- 168
Ilustración 13-18: Página de inserción en base de datos correcta ------------------------------------------------- 168
Ilustración 13-19: Página para la inserción de ontologías ------------------------------------------------------------ 169
Ilustración 13-20: Inserción del nombre de la ontología -------------------------------------------------------------- 169
Ilustración 13-21: Inserción del enlace a la ontología ----------------------------------------------------------------- 169
Ilustración 13-22: Listado de ontologías almacenadas ---------------------------------------------------------------- 170
Ilustración 13-23: Consultas SPARQL --------------------------------------------------------------------------------------- 170
Ilustración 13-24: Selección de la base de datos en la que realizar la consulta --------------------------------- 171
Ilustración 13-25: Selección del formato para los resultados -------------------------------------------------------- 171
Ilustración 13-26: Caja de texto para la query SPARQL --------------------------------------------------------------- 171
Ilustración 13-27: Resultado de la consulta (query) en la base de datos ----------------------------------------- 172
Ilustración 13-28: Administración de scripts ----------------------------------------------------------------------------- 172
Ilustración 13-29: Selección del archivo del script ---------------------------------------------------------------------- 173
Ilustración 13-30: Selección de la página a la que pertenecerá el script ----------------------------------------- 173
x
Ilustración 13-31: Scripts de cada página del proxy -------------------------------------------------------------------- 173
Ilustración 13-32: Visualizador de scripts---------------------------------------------------------------------------------- 174
Ilustración 13-33: Administrador de páginas web del proxy --------------------------------------------------------- 174
Ilustración 13-34: Identificador de la página ----------------------------------------------------------------------------- 175
Ilustración 13-35: Enlace de la página web ------------------------------------------------------------------------------- 175
Ilustración 13-36: Listado de las páginas registradas en el proxy -------------------------------------------------- 175
Ilustración 13-37: Página con un visualizador de tweets -------------------------------------------------------------- 176
Ilustración 13-38: Página personal de David Buján --------------------------------------------------------------------- 177
Ilustración 13-39: Página dipina --------------------------------------------------------------------------------------------- 177
Ilustración 13-40: Vista de RDF en XML ------------------------------------------------------------------------------------ 178
Ilustración 13-41: Grafo a partir del RDF/XML --------------------------------------------------------------------------- 178
Ilustración 13-42: Demostración de GRDDL ------------------------------------------------------------------------------ 179
Ilustración 13-43: XML de RDF ----------------------------------------------------------------------------------------------- 180
Ilustración 13-44: Grafo de RDF ---------------------------------------------------------------------------------------------- 180
Ilustración 13-45: XML generado a partir de GRDDL ------------------------------------------------------------------- 181
Ilustración 13-46: Grafo a partir de RDF/XML del GRDDL ------------------------------------------------------------- 181
Tabla de bloques de código fuente Código 3-1: Ejemplo de expresión regular en Python ------------------------------------------------------------------- 26
Código 3-2: Declaración de transformación GRDDL en XHTML------------------------------------------------------- 27
Código 3-3: Declaración de transformación GRDDL para hcard con Microformatos --------------------------- 27
Código 3-4: Profile de GRDDL dentro de hcard ---------------------------------------------------------------------------- 28
Código 3-5: Datos de hcard conteninedo el XSL para transformar microformatos hcard en GRDDL ------- 28
Código 5-1: Ejemplo de una función en Python --------------------------------------------------------------------------- 33
Código 5-2: Ejemplo de una clase en Python ------------------------------------------------------------------------------ 33
Código 5-3 Ejemplo de un script (programa) en Python ---------------------------------------------------------------- 34
Código 5-4 Resultado del ejemplo anterior -------------------------------------------------------------------------------- 34
Código 5-5: Ejemplo de fichero urls.py -------------------------------------------------------------------------------------- 39
Código 5-6: Ejemplo models.py ----------------------------------------------------------------------------------------------- 39
Código 5-7: Traducción SQL de models.py --------------------------------------------------------------------------------- 39
Código 5-8: Ejemplo de views.py---------------------------------------------------------------------------------------------- 40
Código 5-9: Asignación de direcciones proxy ------------------------------------------------------------------------------ 42
Código 5-10: Asignación de urls en Django -------------------------------------------------------------------------------- 42
Código 5-11: Ejemplo RDF/XML ----------------------------------------------------------------------------------------------- 45
Código 5-12: Ejemplo N-Quads ------------------------------------------------------------------------------------------------ 45
Código 5-13: Ejemplo N-Triples ----------------------------------------------------------------------------------------------- 45
Código 5-14: Ejemplo Turtle --------------------------------------------------------------------------------------------------- 46
Código 5-15: Ejemplo TRiG ----------------------------------------------------------------------------------------------------- 46
Código 5-16: Ejemplo RSS (con RDF) ----------------------------------------------------------------------------------------- 47
Código 5-17: Ejemplo GRDDL (Sobre HTML) ------------------------------------------------------------------------------- 47
Código 5-18: Ejemplo RDFa (Sobre HTML) --------------------------------------------------------------------------------- 48
Código 5-19: Ejemplo Atom 1.0 ----------------------------------------------------------------------------------------------- 49
xi
Código 5-20: Ejemplo Json ------------------------------------------------------------------------------------------------------ 49
Código 5-21: Ejemplo DOT (Grafos) ------------------------------------------------------------------------------------------ 49
Código 5-22: Ejemplo 1º de uso básico con restkit ----------------------------------------------------------------------- 58
Código 5-23: Ejemplo 2º de uso básico con restkit ----------------------------------------------------------------------- 58
Código 5-24: Ejemplo de lenguaje DOT en Graphviz --------------------------------------------------------------------- 60
Código 5-25: Código de ejemplo de Python Graph ----------------------------------------------------------------------- 63
Código 6-1: urls.py ---------------------------------------------------------------------------------------------------------------- 67
Código 6-2: manager/urls.py --------------------------------------------------------------------------------------------------- 68
Código 6-3: settings.py ----------------------------------------------------------------------------------------------------------- 69
Código 6-4: Fragmento de código de urls.py ------------------------------------------------------------------------------- 69
Código 6-5: Fragmento de código de la función de manager/rdf ---------------------------------------------------- 70
Código 6-6: código del método de descarga dentro de utils ----------------------------------------------------------- 71
Código 6-7: Código del método para tratar las subidas locales de RDF -------------------------------------------- 72
Código 6-8: Código para el almacenaje de RDFs en la base de datos ----------------------------------------------- 72
Código 6-9: Modelo de base de datos para las ontologías en Django ---------------------------------------------- 73
Código 6-10: Método que interactúa con las ontologías de la BD --------------------------------------------------- 74
Código 6-11: Método encargado de la página de queries -------------------------------------------------------------- 75
Código 6-12: Método encargado de la ejecución de queries SPARQL ----------------------------------------------- 75
Código 6-13: Método para añadir una web proxy ------------------------------------------------------------------------ 76
Código 6-14: Método para la eliminación de páginas web proxy ---------------------------------------------------- 77
Código 6-15: Método para la subida de scripts al servidor ------------------------------------------------------------- 78
Código 6-16: Método para la visualización de los scripts --------------------------------------------------------------- 78
Código 6-17: Fragmento de código de urls.py ----------------------------------------------------------------------------- 79
Código 6-18: Fragmento de código de /manager/urls.py -------------------------------------------------------------- 79
Código 6-19: manager/views.py----------------------------------------------------------------------------------------------- 80
Código 6-20: templates/registration/login.html -------------------------------------------------------------------------- 81
Código 6-21: ModifyBody.py de la página dbujan ------------------------------------------------------------------------ 87
Código 6-22: ModifyBody.py de la página slok ---------------------------------------------------------------------------- 90
Código 6-23: Comienzo del fichero ModifyBody.py por defecto ------------------------------------------------------ 91
Código 6-24: Método de la lógica en ModifyBody.py por defecto --------------------------------------------------- 92
Código 6-25: Método para modificación de la cabecera del HTML que está en ModifyBody.py ------------- 93
Código 6-26: Método para creación de todas las pestañas en ModifyBody.py ----------------------------------- 95
Código 6-27: Creación de una única pestaña en ModifyBody.py ----------------------------------------------------- 96
Código 6-28: Métodos para parser GRDDL en ModifyBody.py -------------------------------------------------------- 97
Código 6-29: Método que modifica el cuerpo del HTML en ModifyBody.py --------------------------------------- 98
Código 6-30: ModifyBodyBase.py --------------------------------------------------------------------------------------------- 99
Código 6-31: Reimplementación simple para un script del proxy -------------------------------------------------- 100
Código 6-32: Importar métodos del módulo Db ------------------------------------------------------------------------- 101
Código 6-33: Importar métodos del módulo Rdf ------------------------------------------------------------------------ 101
Código 6-34: Importar métodos del módulo utils ----------------------------------------------------------------------- 102
Código 13-1: Instalación de setuptools y pip ----------------------------------------------------------------------------- 152
Código 13-2: Instalación Django -------------------------------------------------------------------------------------------- 152
Código 13-3: Instalación Restkit --------------------------------------------------------------------------------------------- 152
Código 13-4: Instalación Pygments ----------------------------------------------------------------------------------------- 152
xii
Código 13-5: Instalación Beautiful Soup ----------------------------------------------------------------------------------- 152
Código 13-6: Instalación Lxml ------------------------------------------------------------------------------------------------ 152
Código 13-7: Obtención del código fuente de Graphviz --------------------------------------------------------------- 153
Código 13-8: Instalación de Graphviz--------------------------------------------------------------------------------------- 153
Código 13-9: Instalación Python-graphviz--------------------------------------------------------------------------------- 153
Código 13-10: Instalación Raptor -------------------------------------------------------------------------------------------- 154
Código 13-11: Instalación Rasqal -------------------------------------------------------------------------------------------- 154
Código 13-12: Instalación LibRDF -------------------------------------------------------------------------------------------- 154
Código 13-13: Imstalación Python Redland bindings------------------------------------------------------------------- 154
Código 13-14: Archivo de configuración de Nginx ---------------------------------------------------------------------- 156
Código 13-15: Configuración de Django para uWSGI ------------------------------------------------------------------ 156
Código 13-16: Script para deploy de aplicaciones Django con uWSGI --------------------------------------------- 157
Código 13-17: Script de comando uWSGI --------------------------------------------------------------------------------- 159
Código 13-18: Usuario y clave de la BD en settings.py----------------------------------------------------------------- 159
Código 13-19: Usuarío y clave de la BD en manager/views.py ------------------------------------------------------ 159
Código 13-20: Comando para la creación de las tablas de Django en la BD ------------------------------------- 159
Código 13-21: Comando para arrancar demonio de Nginx ----------------------------------------------------------- 160
Código 13-22: Comando para arrancar script de deploy -------------------------------------------------------------- 160
Código 13-23: Ejemplo de query SPARQL ---------------------------------------------------------------------------------- 171
PROYECTO FIN DE CARRERA
1
1. INTRODUCCIÓN
1.1 ACERCA DEL PROYECTO
En la actualidad, la Web está llena de páginas dispersas por todo el planeta, de
diferentes sitios y con contenido diverso y variado. Por ello, cada vez es más complejo
unificar, encontrar, organizar y obtener datos de ellas.
La Web Semántica intenta hacer todo esto más fácil proporcionándonos
nuevas tecnologías y herramientas como son los RDF, Ontologías, Endpoints
SPARQL, Linked Data, etc. Para ello, las páginas actuales deben actualizarse y ser
modificadas de forma que puedan utilizar toda la potencia de la Web Semántica, cuyo
objetivo no es más que el de crear una Web (en su totalidad) llena de metadatos.
Este proyecto está orientado hacia la Web Semántica. Es decir, trabaja con
páginas web que estén preparadas para trabajar con metadatos, les extrae esos
metadatos y los representa de forma visible al ojo humano.
Sin embargo, debido al diseño flexible del proyecto, éste puede usarse a su vez
para trabajar de otras formas que no tengan que ver con los metadatos. Una breve
explicación de esto último es que al tratarse el proyecto de un proxy que modifica el
comportamiento de la página que se solicita, por defecto crea una visualización
adecuada de los metadatos. Sin embargo, es posible modificar este último
comportamiento y hacer que en vez de visualizar metadatos realice otras utilidades,
como por ejemplo, cambiar el aspecto visual de una página web.
1.2 ACERCA DE LA DOCUMENTACIÓN
Esta documentación pretende ser un punto de referencia para interiorizar y
entender el proyecto, desde los pilares más básicos como es el diseño y la idea en sí
(incluyendo una explicación de ciertos conceptos asociados al proyecto como son la
Web Semántica y las Ontologías), hasta la planificación de cómo se ha desarrollado.
Asimismo, también cuenta al final con el anexo “Manual de Usuario” donde se
explicará detalladamente el uso de la aplicación web para el manejo de su
administración.
Los diferentes capítulos de los que consta esta memoria son:
1. INTRODUCCIÓN
2
Definición del proyecto: Se explica qué es lo que se pretende conseguir con
este proyecto, es decir su objetivo, así como su alcance.
Justificación: Cómo se justifica el desarrollo del proyecto. La razón por la cual
se ha realizado, así como los beneficios que puede aportar.
Conceptos básicos: Definición y explicación de conceptos que ayudarán a
entender la documentación en su totalidad.
Recursos utilizados: Qué recursos han sido utilizados para el desarrollo,
puesta en marcha y pruebas del proyecto.
Diseño del proyecto: Una explicación a grandes rasgos de cómo está
organizado el proyecto, las ventanas que utiliza, etc. (mencionar que se
explicarán en más profundidad más adelante, en el anexo “Manual de
Usuario”).
Desarrollo del proyecto: Cuál ha sido el desarrollo, cómo se ha organizado el
proyecto en el ámbito del desarrollo, componentes, etc.
Usos alternativos: Qué usos alternativos se le pueden dar al proyecto además
del cual para el que ha sido creado en un primer momento, es decir, la
extracción/inserción de metadatos en páginas web.
Planificación: Cuál ha sido el diario de planificación, diagramas de Gantt,
plazos establecidos, calendarios, etc.
Conclusión: Conclusión global del proyecto, tanto en aprendizaje propio a lo
largo del recorrido como el aporte que supone el proyecto a la Web Semántica.
Manual de usuario: Documento que explica cómo hacer uso de las herramientas
desarrolladas a nivel de usuario.
PROYECTO FIN DE CARRERA
3
2. DEFINICIÓN DEL PROYECTO
2.1 OBJETIVOS
El proyecto está principalmente orientado a solucionar problemas que tienen
que ver con los metadatos, pese a que como veremos más adelante, también pueda
ser utilizado con otros fines. Uno de los objetivos es el de hacer que una página sin
metadatos pueda ser enriquecida con ellos. Debido a que el servidor se trata de un
servido proxy, en la práctica la página original no contendría los metadatos
introducidos, sino que el proxy al cual el usuario hace la petición de enriquecer la
página indicada por él/ella, tras combinar la página original con los metadatos a
insertar (que previamente han sido introducidos y almacenados en el propio servidor
proxy) devolverá al usuario una página casi idéntica a la original solo que enriquecida
con metadatos.
Por otra parte, también existe el problema de que a pesar de que algunas
páginas tienen metadatos, estos no están adecuadamente representados visualmente
dificultando su identificación y comprensión para los humanos. Por ello, otro de los
objetivos que se persiguen es el de poder extraer los metadatos de las páginas y
posteriormente, tras generar una página casi idéntica a la original, representarlos
visualmente en ella en un formato más cómodo de visualizar por el ser humano
(concretamente en formato XML y también a modo de grafo).
Así expuesta la situación, este proyecto persigue los siguientes objetivos:
Investigación de las posibilidades que ofrece la Web Semántica en páginas sin
metadatos.
Investigación de las posibilidades que ofrece la Web Semántica en las páginas
con metadatos.
Documentación sobre el proyecto para posterior aprendizaje y puesta en
funcionamiento.
Extracción de metadatos en páginas semantizadas.
Añadir metadatos a páginas semantizadas y/o sin semantizar.
Creación de una estructura flexible del servidor proxy donde el comportamiento
por defecto de éste (extracción y añadido de metadatos) no sea la única
posibilidad.
2. DEFINICIÓN DEL PROYECTO
4
Desarrollar un backend mediante el cual se pueda administrar y depurar
metadatos del proxy.
Desarrollar una pequeña API para trabajar con metadatos.
2.2 ALCANCE
2.2.1 Alcance del proyecto
Los límites generales del proyecto son:
Realización de una investigación sobre las tecnologías que mejor se adapten a
las necesidades del proyecto y posterior documentación.
Implementación del proyecto con su backend de administración y depuración,
así como el servidor proxy.
Implementación de varios scripts para diferentes páginas como prueba de
concepto y la redacción de una documentación adecuada que describa el
proyecto.
2.2.2 Alcance de la investigación
Los límites de la investigación son:
Realización de una investigación sobre las tecnologías utilizadas en la Web
Semántica para la descripción de los contenidos, como RDF, OWL, RDFa o
GRDDL, además de SPARQL, el lenguaje de consulta más utilizado dentro de
la Web Semántica.
Realización de una investigación sobre los pilares de la infraestructura, como
son el lenguaje de programación Python, el framework para la creación del
portal Django y las diferentes librerías usadas, las cuales se describirán más
adelante.
2.2.3 Alcance de la documentación
Los límites de la documentación son:
Realización de una documentación donde se expliquen los conceptos básicos
necesarios para entender el proyecto, la herramienta (el servidor proxy) y la
documentación.
PROYECTO FIN DE CARRERA
5
Realización de una documentación donde se explique el funcionamiento de la
herramienta (el servidor proxy).
Realización de una documentación donde se explique el proceso, así como las
diferentes tecnologías/herramientas utilizadas para el desarrollo del proyecto.
2.2.4 Alcance de la herramienta
Este proyecto tiene un alcance un tanto global, ya que ha sido diseñado de
forma que resulte lo más flexible posible. Esto último, hace posible que la mayor parte
las páginas existentes puedan aprovecharse de esta herramienta. Sin embargo, para
la realización de las pruebas de concepto pertinentes hemos seleccionado y hecho
uso de una serie de páginas específicas:
Página personal de Dr. Diego López de Ipiña:
Esta página constituye la página principal sobre la cual se ha
experimentado con la extracción, manejo y representación tanto en XML como
en forma de grafo de metadatos. Más específicamente, se ha realizado una
extracción de RDFa mediante GRDDL, así como un análisis de archivos RDFa.
Página personal de David Bujan:
En la página personal de David Buján se ha realizado una prueba de
concepto para demostrar que este proyecto no sólo vale para el añadido,
manejo y extracción de metadatos, sino para todo lo que se nos pueda ocurrir
como cambiar el estilo de una página por completo.
Servidor propio para pruebas:
Al igual que la página de David Buján, en ésta se han hecho pruebas
diferentes a las de extracción/manejo de metadatos. Sin embargo, en un punto
del desarrollo también nos sirvió para experimentar con RDFa y GRDDL, así
como con diferentes ontologías.
2.3 PRODUCTO FINAL
Este proyecto va a dar lugar a un producto final que a su vez, se compone de
una serie de productos finales o herramientas:
Backend:
o Administrador de usuarios.
2. DEFINICIÓN DEL PROYECTO
6
o Administrador de las páginas que maneja el servidor proxy.
o Administrador de scripts.
Depuración:
o Administrador de RDFs.
o Administrador de Ontologías.
o Consultas SPARQL.
Proxy:
o Script por defecto para la extracción de metadatos (de modo que el
comportamiento por defecto de servidor proxy sea el
manejo/manipulación de metadatos).
o API flexible para modificar el comportamiento del proxy.
o Carga de scripts individuales e independientes para cada página.
2.4 DESCRIPCIÓN DE LA REALIZACIÓN
2.4.1 Método de desarrollo:
El método de desarrollo utilizado para este proyecto será el famoso método de
desarrollo por fases. El método de desarrollo por fases es muy efectivo cuando la
complejidad de un proyecto es alta. De esta forma el seguimiento, la corrección y la
organización es más fácil y requiere menos tiempo. Para ello se han definido las
siguientes fases:
Análisis:
En esta fase se expondrá el problema principal, se analizará y se
buscará una solución. Para ello se limitará a los aspectos principales para el
planteamiento del problema dejando a un lado aquellos que resulten
irrelevantes y/o poco importantes. Asimismo, también se identificarán y
establecerán las entradas del problema, así como las salidas o resultados
deseados.
Diseño:
En esta fase se diseñará una solución adecuada para solventar el
problema, por lo que constituye la parte más difícil del proceso de resolución
PROYECTO FIN DE CARRERA
7
del problema. Es importante tener en cuenta la flexibilidad que se desea
conseguir, ya que la flexibilidad de la herramienta viene dada por un diseño
flexible.
Implementación:
Esta etapa consiste en implementar o escribir el algoritmo como un
programa de computadora en un lenguaje de programación, convirtiendo cada
paso del algoritmo en instrucciones en el lenguaje de programación. Se
requiere el conocimiento de un lenguaje de programación particular en lo
referente a su gramática, sintaxis y semántica. Asimismo, se utilizarán los tipos
y estructuras de datos más adecuados y se intentará optimizar lo máximo
posible el rendimiento.
Verificación y pruebas:
Esta fase consiste en probar la herramienta completa así como verificar
las pruebas realizadas para comprobar que realiza la función/tarea que se
esperaba. Para ello se necesitan datos y situaciones de prueba, que en nuestro
caso son páginas web para usar con el proxy, sobre los cuales ejecutar los
scripts verificando el correcto funcionamiento de estos últimos.
Documentación:
Esta última etapa consiste en la redacción de una documentación del
proyecto en la que incluirán explicaciones e indicaciones de todo lo referente al
proyecto desarrollado: manuales, organización del proyecto, fases seguidas en
la realización del proyecto, tecnologías usadas, glosario, enlaces, etc.
2.4.2 Tareas principales:
A continuación se van a mostrar tareas principales. A su vez, cada tarea tiene
varias subtareas lo que hace que la tabla de tareas esté dividida correctamente y
facilite su lectura. Es importante recalcar que no todos los días se acumulaban 3 horas
de trabajo. En ocasiones se han llegado hasta las 10 horas de trabajo y muy pocas
veces la carga de trabajo diaria era inferior a las 3 horas.
2. DEFINICIÓN DEL PROYECTO
8
Por otra parte, el diagrama de Gantt asociado a las tareas es el siguiente:
Ilustración 2-1: Tabla de tareas
PROYECTO FIN DE CARRERA
9
Ilustración 2-2: Diagrama de Gantt
2. DEFINICIÓN DEL PROYECTO
10
2.5 ORGANIZACIÓN Y EQUIPO
La organización del proyecto está formada por un comité de dirección, uno de
seguimiento y 2 grupos de trabajo como podemos ver en el siguiente esquema:
Comité de dirección:
Este comité tiene como misión ser el órgano que tome las decisiones en
el proyecto, y por tanto, sobre el cual recaerá la responsabilidad de dicho
proyecto. En en este caso en particular este organismo lo comforma el Dr.
Diego López de Ipiña.
Comité de seguimiento:
Órgano ejecutivo del proyecto. Al igual que el comité de dirección, éste
también tomará decisiones y hará de representante de diferentes
departamentos. En en este caso en particular este organismo lo comforma el
Dr. Diego López de Ipiña.
Grupo de trabajo:
Este grupo será el encargado del desarrollo del proyecto en sí. Su labor
consistirá en el desarrollo, instalación e implantación del sistema.
Ilustración 2-3: Esquema organizativo
PROYECTO FIN DE CARRERA
11
Se organizarán reuniones esporádicas (mensuales) para la toma de
decisiones, así como para comentar y llegar a soluciones para los diferentes
problemas que vayan surgiendo a raíz de la realización del proyecto.
En este caso en particular, seremos Iraide Diaz y Xabier Larrakoetxea
los que formemos este grupo.
Dentro del equipo de trabajo hay varios puestos diferentes y como se ha
comentado previamente todos estos puestos se han llevado a cabo por las mismas
personas. Es decir, las personas que han participado en este proyecto han tenido
varios puestos de trabajo diferentes dentro de la estructura organizativa a lo largo de
todo el proyecto. A continuación, se pueden observar los diferentes puestos existentes
dentro del equipo de trabajo.
Equipo de trabajo
o Jefe de proyecto:
La tarea de este miembro es la de organizar y dirigir el equipo
encargado del proyecto, así como el de asegurarse el cumplimento de los
plazos.
o Ingenieros informáticos:
Desarrollarán la aplicación en su totalidad. Además de ello, se
encargarán también de hacer la configuración e implantación del sistema.
o Técnicos:
Podrían ser los mismos informáticos quienes realizaran el
mantenimiento del sistema, pero el hecho de tener un equipo técnico que
de apoyo a los ingenieros informáticos es importante. Su tarea será la de
mantener el servidor en perfecto funcionamiento en todo momento.
o Personal externo:
Pese a que no es un equipo de trabajo en sí, es importante recalcar
que siempre existirá un personal externo al proyecto. Este personal,
brindará ayuda y soporte en diferentes campos relacionados con el
proyecto, ya sea en una tecnología software como puede ser un IDE de
desarrollo o un lenguaje de programación, o tecnología hardware como
puede ser un PC en el puesto de servidor.
2. DEFINICIÓN DEL PROYECTO
12
2.6 PRESUPUESTO
Las horas han sido variables durante el transcurso del proyecto, pero
aproximadamente las cantidades son las siguientes:
Días laborables: 20días/mes
Horas laborables: 5h/día
Perfil Carga Precio Importe
Jefe de proyecto 4 días 1.000€/mes 200€
Administrador/Técnico 15 días 800€/mes 600€
Programador 1 130 días 500€/mes 3.250€
Programador 2 130 días 500€/mes 3.250€
Total: 7.300,00€
2.7 CONDICIONES DE EJECUCIÓN
Entorno de trabajo
Los lugares de trabajo donde se desarrollará el proyecto serán
principalmente las instalaciones de la facultad ESIDE de la Universidad de
Deusto: las diferentes aulas informáticas, los laboratorios de DeustoTech... Sin
embargo, debido a problemas de espacio o a otros motivos algunos de los
trabajos también podrán ser realizados desde las casas particulares de los
desarrolladores.
El calendario estará sujeto al hecho de que los desarrolladores son
alumnos de la facultad de Ingeniería de Deusto, con lo cual el horario será
bastante flexible dependiendo de las necesidades y los compromisos (horas de
clase, reuniones…) de los propios desarrolladores. Por tanto, no estarán
sujetos a un horario en particular siempre y cuando se cumplan las horas
acordadas previamente (15 horas semanales).
Hardware
o 2 Ordenadores portátiles propiedad de los propios desarrolladores.
o 2 Ordenadores de sobremesa propiedad de los propios desarrolladores.
PROYECTO FIN DE CARRERA
13
Software
o Sistema Operativo GNU/Linux (distribuciones Arch Linux y Slackware).
o Entorno de desarrollo: Geany.
o Navegadores: Mozilla Firefox y/o Google Chrome.
o Control de versiones: Git.
Control de cambios:
En el caso de existir alguna petición de modificación o ampliación en los
requisitos durante la realización el proyecto, ésta deberá estar sujeta a una
serie de directrices que deberán ser cumplidas:
1. Comunicación del/los cambio/s al jefe de proyecto.
2. Presentación de él/ellos al jefe de proyecto.
3. Análisis de los cambios por parte del jefe de proyecto y del comité
de seguimiento.
4. Emisión del veredicto y en caso de ser aprobado, modificación tanto
de la planificación como del proyecto en sí.
Las reuniones con los trabajadores podrán ser diarias o semanales,
mientras que las reuniones con el director de proyecto serán cada 3 semanas o
mensuales.
Recepción de productos:
Tras terminar el desarrollo del proyecto y las pruebas del mismo, el
servidor será testeado por el jefe de proyecto y dará su aprobación. Una vez
aprobado, pasará por una serie de pruebas posteriores las cuales durarán 2
semanas. Tras este periodo de tiempo, se considerará que la herramienta es
estable y se procederá a su instalación.
Tras las pruebas, se procederá a crear una documentación detallada
sobre el proyecto (la cual posteriormente será guardada por el jefe de proyecto)
que incluirá como anexo un Manual de Usuario que explicará cómo utilizar y
configurar el servidor para enriquecer semánticamente páginas y manejar los
metadatos, así como para modificar el comportamiento por defecto del servidor
proxy posibilitando así la realización de otros trabajos/tareas por parte de éste.
PROYECTO FIN DE CARRERA
15
3. CONCEPTOS BÁSICOS
3.1 PROXY
Un proxy pertenece a una red informática donde modifica el comportamiento y
la ruta de dicha red. Un proxy lo que hace es representar a otro objeto dentro de dicha
red.
Dicho de otra forma: Un proxy, en una red informática, es un programa o
dispositivo que realiza una acción en representación de otro, esto es, si una hipotética
máquina a solicita un recurso a una máquina c, lo hará mediante una petición a la
máquina b; c entonces no sabrá que la petición procedió originalmente de a. Su
finalidad más habitual es la de servidor proxy, que sirve para interceptar las
conexiones de red que un cliente hace a un servidor de destino, por varios motivos
posibles como seguridad, rendimiento o anonimato.
3.1.1 Tipos
Forward proxies:
Los forward proxies son proxies donde el cliente hace una llamada al
servidor externo al que quiere conectarse. Los forward proxies son capaces de
recuperar de una amplia gama de páginas. Los términos forward proxy y
forwarding proxy son una descripción general de la conducta (reenvío de
tráfico) y por lo tanto ambigua. A excepción del proxy inverso (reverse proxy),
cuando hablamos de proxies se suele hacer referencia al forward proxy.
Open proxies:
Ilustración 3-1: Ilustración de un forward proxy
3. CONCEPTOS BÁSICOS
16
Un proxy abierto u open proxy es un servidor proxy de reenvío que es
accesible por cualquier usuario de Internet. Este tipo de proxy permite a los
usuarios anónimos ocultar su dirección IP mientras navegan por la Web o usar
otros servicios de Internet.
Reverse proxies:
Un proxy inverso es un servidor proxy que se a simple vista de los
clientes parece un servidor común. Las solicitudes se envían a uno o más
servidores de origen que atenderán la solicitud y la respuesta se devuelve
como si viniera directamente del servidor proxy, pero en realidad no es así.
Los reverse proxies están instalados en conjunto de uno o más
servidores Web. Todo el tráfico procedente de Internet y con un destino de uno
de los servidores web pasa a través del servidor proxy. El uso del “reverse” se
origina en el proxy, ya que el proxy inverso se encuentra más cerca del servidor
web y sirve sólo un conjunto limitado de sitios web, al contrario que otros tipos
de proxy.
Existen varios tipos de reverse proxy:
o Cifrado / Aceleración SSL
o Load balancing (repartir la carga)
o Servir/cachear contenido estático
Ilustración 3-2: Ilustración de un proxy abierto
Ilustración 3-3: Ilustración de un proxy inverso
PROYECTO FIN DE CARRERA
17
o Compresión
o Spoon feeding
o Seguridad
o Extranet Publishing
3.1.2 Funcionamiento
Un proxy permite a otros equipos conectarse a una red de forma indirecta a
través de él. Cuando un equipo de la red desea acceder a una información o recurso a
través de éste, es realmente el proxy quien realiza la comunicación y a continuación
traslada el resultado al equipo inicial. En algunos casos, esto se hace de este modo ya
que no es posible la comunicación directa, mientras que en otros suele deberse a que
el proxy añade una funcionalidad adicional como puede ser la de almacenar los
últimos resultados obtenidos (p.ej.: una página web) en una caché que permita
acelerar sucesivas consultas coincidentes. Con esta denominación general de proxy
se agrupan diversas técnicas.
3.2 WEB SEMÁNTICA
3.2.1 Definición
La Web Semántica es una Web extendida, dotada de mayor significado en la
que cualquier usuario en Internet podrá encontrar respuestas a sus preguntas de
forma más rápida y sencilla gracias a una información mejor definida. Al dotar a la
Web de más significado y, por lo tanto, de más semántica, se pueden obtener
soluciones a problemas habituales en la búsqueda de información gracias a la
utilización de una infraestructura común, mediante la cual, es posible compartir,
procesar y transferir información de forma sencilla. Esta Web extendida y basada en el
significado, se apoya en lenguajes universales que resuelven los problemas
ocasionados por una Web carente de semántica en la que, en ocasiones, el acceso a
la información se convierte en una tarea difícil y frustrante. Para ello, se apoya en
ciertas herramientas y técnicas como pueden ser las ontologías.
3.2.2 Utilidades
La Web Semántica ha cambiado la forma en la que navegamos. A simple vista
la Web Semántica no parece estar ahí, pero su presencia es muy importante. En la
comunicación que vemos en Internet normalmente la Web Semántica está de por
medio ya que las páginas están interconectadas y tienen datos “extra” (metadatos) que
3. CONCEPTOS BÁSICOS
18
nosotros no reconocemos o percibimos, pero que ciertas herramientas software (tales
como los buscadores) que los necesitan, lo usan para llevar a cabo sus tareas.
La Web ha cambiado significativamente la forma en la que nos comunicamos,
hacemos negocios e incluso trabajamos. Gracias a ella tenemos acceso a millones de
recursos en cualquier momento, independientemente de nuestra situación geográfica e
idioma. Si bien es cierto que estos factores han contribuido al éxito de la Web. Sin
embargo, al mismo tiempo, estos factores que han propiciado el éxito de la Web,
también han originado sus principales problemas: sobrecarga de información y
heterogeneidad de fuentes de información con el consiguiente problema de
interoperabilidad.
La Web Semántica trata de resolver estos los problemas descritos permitiendo
a los usuarios delegar tareas en software. Gracias a la semántica en la Web, ahora las
herramientas software pueden procesar su contenido, razonar y realizar deducciones
lógicas de tal forma que las resoluciones a problemas cotidianos se automatizan y se
consiguen resultados más exactos.
Existen ciertos escenarios en los que la Web Semántica puede ayudar a
solucionar problemas o ayudar con la realización de ciertas tareas. Como ejemplos
tenemos:
Búsquedas en internet (por ejemplo, para llevar a cabo búsquedas más
precisas y exhaustivas con un buscador como Google).
Obtención de datos desde una aplicación móvil (por ejemplo, capturar posición
de mapas en una aplicación para Android).
Interconexión de Webs (por ejemplo, para conectar páginas personales de los
profesores de una universidad).
3.2.3 Funcionamiento
PROYECTO FIN DE CARRERA
19
Para obtener una adecuada definición de los datos, la Web Semántica hace
uso de varias tecnologías y mecanismos:
RDF:
El Marco de Descripción de Recursos (del inglés Resource Description
Framework, RDF) es un framework para metadatos en la World Wide Web
(WWW), desarrollado por el World Wide Web Consortium (W3C). Proporciona
información descriptiva sobre los recursos que se encuentran en la Web y que
se utiliza, por ejemplo, en catálogos de libros, directorios, música, proyectos,
documentos, etc.
OWL (Ontologías):
OWL es el acrónimo del inglés Ontology Web Language, un lenguaje de
marcado para publicar y compartir datos usando ontologías en la WWW. OWL
tiene como objetivo facilitar un modelo de marcado construido sobre RDF y
codificado en XML. Como definición simple se podría decir que lo que hace
OWL es proporcionar un lenguaje para definir ontologías estructuradas que
pueden ser utilizadas a través de diferentes sistemas.
SPARQL:
SPARQL es un acrónimo recursivo del inglés SPARQL Protocol and
RDF Query Language. Se trata de un lenguaje estandarizado para la consulta
de grafos RDF que permite hacer búsquedas sobre los recursos de la Web
Semántica utilizando distintas fuentes de datos.
Ilustración 3-4: Estructura de la web semántica
3. CONCEPTOS BÁSICOS
20
3.3 ONTOLOGÍAS
Dentro de la informática cuando nos referimos a ontologías, se hace referencia
a la formulación de un exhaustivo y riguroso esquema conceptual dentro de un
dominio dado, para conseguir un intercambio de información más coherente y fácil
entre diferentes sistemas.
Un uso común tecnológico actual del concepto de ontología, en este sentido
semántico, lo encontramos en la inteligencia artificial y la representación del
conocimiento. En algunas aplicaciones, se combinan varios esquemas en una
estructura de facto completa de datos, que contiene todas las entidades relevantes y
sus relaciones dentro del dominio.
Los programas informáticos pueden utilizar así este punto de vista de la
ontología para una variedad de propósitos, incluyendo el razonamiento inductivo, la
clasificación, y una variedad de técnicas de resolución de problemas.
Para definir estas ontologías existen actualmente lenguajes o más bien
estándares (W3C) que lo posibilitan como es el caso de OWL.
Ilustración 3-5: Ejemplo de ontología
PROYECTO FIN DE CARRERA
21
3.4 SPARQL
SPARQL (SPARQL Protocol and RDF Query Language) es un lenguaje
estandarizado para la consulta de grafos RDF que permite hacer búsquedas sobre los
recursos de la Web Semántica utilizando distintas fuentes de datos. Básicamente
SPARQL sería de la misma forma que SQL es para los datos comunes, pero orientado
a la web semántica. Esto significa que SPARQL es la forma que existe para hacer
consultas en una base de datos donde previamente han sido almacenados metadatos.
Al igual que sucede con SQL, es necesario distinguir entre el lenguaje de
consulta y el motor para el almacenamiento y recuperación de los datos. Por este
motivo, existen múltiples implementaciones de SPARQL, generalmente ligados a
entornos de desarrollo y plataformas tecnológicas.
En un principio SPARQL únicamente incorpora funciones para la recuperación
de sentencias RDF. Sin embargo, algunas propuestas también incluyen operaciones
para el mantenimiento (creación, modificación y borrado) de datos.
3.5 LINKED DATA
Los Datos Enlazados es la forma que tiene la Web Semántica de vincular los
distintos datos que están distribuidos en la Web, de forma que se referencian de la
misma forma que lo hacen los enlaces de las páginas web.
De la misma forma que la web de la web del hipertexto, la web de los datos se
construye mediante documentos en la web. Sin embargo, y a diferencia de la web del
hipertexto, donde los enlaces son relaciones entre puntos de los documentos escritos
en HTML, los datos enlazan cosas arbitrarias que se describen en RDF.
Los datos publicados en la Web se pueden vincular a otros, de forma que las
personas y las máquinas puedan explorar la web de los datos, pudiendo llegar a
información relacionada que se hace referencia desde otros datos iniciales. Por tanto,
Linked Data permite construir la Web de los datos, es decir, una gran base de datos
interconectados y distribuidos en la Web, lo cual los vuelve más útiles.
Los Datos Enlazados, como parte de la Web Semántica, se basa en la
aplicación de ciertos principios básicos y necesarios, que fomentarán el crecimiento de
la Web, tanto a nivel de los documentos HTML (vista clásica de la Web), como a nivel
de los datos expresados en RDF (vista de la Web Semántica). Sir Tim Berners-Lee
definió cuatro principios que caracterizan los datos vinculados en su ponencia de
presentación para el W3C.
3. CONCEPTOS BÁSICOS
22
1. Utilizar URIs para identificar los recursos publicados en la Web.
2. Aprovechar el HTTP de la URI para que la gente pueda localizar y consultar (es
decir, desreferenciar) estos recursos.
3. Proporcionar información útil acerca del recurso cuando la URI haya sido
desreferenciada.
4. Incluir enlaces a otras URI relacionadas con los datos contenidos en el recurso,
de forma que se potencie el descubrimiento de información en la Web.
Para conseguir tener los datos interconectados y consecuentemente poder
permitir reutilizar la información de cualquier manera esperada o inesperada
(ofreciendo un valor añadido a la Web), se deben respetar los cuatro pasos anteriores.
3.6 EXPRESIONES REGULARES
Una expresión regular, a menudo llamada también patrón, es una expresión
que describe un conjunto de cadenas sin enumerar sus elementos. Por ejemplo, el
grupo formado por las cadenas Handel, Händel y Haendel se describe mediante el
patrón "H(a|ä|ae)ndel". La mayoría de las formalizaciones proporcionan los siguientes
constructores: una expresión regular es una forma de representar a los lenguajes
regulares (finitos o infinitos) y se construye utilizando caracteres del alfabeto sobre el
Ilustración 3-6: Conjunto de datos interconectados entre sí que componen la "Nube de Linked Data"
PROYECTO FIN DE CARRERA
23
cual se define el lenguaje. Específicamente, las expresiones regulares se construyen
utilizando los operadores unión, concatenación y clausura de Kleene. Además cada
expresión regular tiene un autómata finito asociado.
En el área de la programación, las expresiones regulares son un método por
medio del cual se pueden realizar búsquedas dentro de cadenas de caracteres. Sin
importar si la búsqueda requerida es de dos caracteres en una cadena de 10 o si es
necesario encontrar todas las apariciones de un patrón definido de caracteres en un
archivo de millones de caracteres, las expresiones regulares proporcionan una
solución para el problema. Adicionalmente, un uso derivado de la búsqueda de
patrones es la validación de un formato específico en una cadena de caracteres dada,
como por ejemplo fechas o identificadores.
Para poder utilizar las expresiones regulares al programar es necesario tener
acceso a un motor de búsqueda con la capacidad de utilizarlas. Es posible clasificar
los motores disponibles en dos tipos:
Motores para el usuario final
Son programas que permiten realizar búsquedas sobre el contenido de un
archivo o sobre un texto extraído y colocado en el programa. Están diseñados para
permitir al usuario realizar búsquedas avanzadas usando este mecanismo. Sin
embargo es necesario aprender a redactar expresiones regulares adecuadas para
poder utilizarlos eficientemente. Éstos son algunos de los programas disponibles:
grep: programa de los sistemas operativos Unix/Linux.
PowerGrep: versión de grep para los sistemas operativos Windows.
RegexBuddy: ayuda a crear las expresiones regulares en forma interactiva y
luego le permite al usuario usarlas y guardarlas.
EditPad Pro: permite realizar búsquedas con expresiones regulares sobre
archivos y las muestra por medio de código de colores para facilitar su lectura y
comprensión.
Motores para el programador
Permiten automatizar el proceso de búsqueda de modo que sea posible
utilizarlo muchas veces para un propósito específico. Estas son algunas de las
herramientas de programación disponibles que ofrecen motores de búsqueda con
soporte a expresiones regulares:
Java: existen varias bibliotecas hechas para java que permiten el uso de
RegEx, y Sun planea dar soporte a estas desde el SDK
JavaScript: a partir de la versión 1.2 (ie4+, ns4+) JavaScript tiene soporte
integrado para expresiones regulares.
Perl: es el lenguaje que hizo crecer a las expresiones regulares en el ámbito
de la programación hasta llegar a lo que son hoy en día.
3. CONCEPTOS BÁSICOS
24
PCRE: biblioteca de ExReg para C, C++ y otros lenguajes que puedan utilizar
bibliotecas dll (Visual Basic 6 por ejemplo).
PHP: tiene dos tipos diferentes de expresiones regulares disponibles para el
programador, aunque la variante POSIX (ereg) va a ser desechada en PHP 6.
Python: lenguaje de "scripting" popular con soporte a Expresiones Regulares.
.Net Framework: provee un conjunto de clases mediante las cuales es posible
utilizar expresiones regulares para hacer búsquedas, reemplazar cadenas y
validar patrones.
En Python las expresiones regulares tienen una sintaxis la cual podemos
apreciar en la siguiente tabla. Cabe mencionar que no se trata de la tabla completa, ya
que es muy amplia, pero se puede ver lo más importante:
Patrón Descripción
^ Principio de linea
$ Final de linea
. Cualquier character salvo cambio de linea (con la opción m adopta
también cambio de linea)
[...] Cualquier character dentro de los corchetes
[^...] Cualquier character diferente dentrod e los corchetes
re* 0 o más ocurrencias
re+ 1 o más ocurrencias
re? 0 o 1 ocurrencias
re{ n} Exactamente “n” ocurrencias
re{ n,} N o más ocurrencias
PROYECTO FIN DE CARRERA
25
re{ n, m} De n a m ocurrencias
a| b A o b
(re) Agrupa expresiones regulares
(?imx) Temporalmente activa las opciones I, m, o x en una expresión
regular dentro del parentesis
(?-imx) Temporalmente desactiva las opciones I, m, o x en una expresión
regular dentro del parentesis
(?: re) Agrupa expresiones regulares sin memorizar la ocurrencia del texto
(?imx: re) Temporalmente desactiva las opciones I, m, o x en una expresión
regular
(?-imx: re) Temporalmente desactiva las opciones I, m, o x en una expresión
regular
(?#...) Comentarío
(?= re) Posición especifica dentro del patron. No tiene rango
(?! re) Posición especifica dentro del patrón negado. No tiene rango.
(?> re) Asocia un patron independiente sin usar “Backtracking”
\w Asocia caracteres de palabras
\W Asocia caracteres de “no palabras”
\s Asocia espacios en blanco. Equivalente a [\t\n\r\f].
3. CONCEPTOS BÁSICOS
26
\S Asocia no espacios en blanco
\d Asocia dígitos. Equivalente a [0-9].
\D Asocia “no dígitos”
\A Asocia principio de un string (cadena de caracteres)
\Z Asocia final de un string.Si existe una nueva linea, lo asocial justo
hasta el comienzo de
\z Asocia final de un string
\G Asocia la posición en la qu ese encotrntro la última asociación
Un ejemplo de uso de expresiones regulares en Python sería este pequeño
snippet de código. Lo que hace es buscar el patron “<body>” indicándole que después
de “<body>” y antes de “>” puede haber: espacios, =, “ o caracteres.
import re
regularExpressionIn = '<body[\w"= ]*>'
reg = re.compile(regularExpressionIn)
m = reg.search(body)
Código 3-1: Ejemplo de expresión regular en Python
3.7 GRDDL
GRDDL son las siglas de Gleaning Resource Descriptions from Dialects of
Languages o en castellano: "Espigar Descripciones de Recursos de Dialectos de
Lenguajes". Una explicación sencilla para GRDDL sería tan simple como “un extractor
de metadatos”. Sin embargo, no es tan simple como parece.
PROYECTO FIN DE CARRERA
27
GRDDL es una forma de indicar una transformación, comúnmente mediante
XSLT, de un documento XHTML o XML para obtener información en RDF. Mediante
esta indicación, una aplicación informática puede extraer de forma automática
información de páginas web estructuradas para integrarla en la Web Semántica.
3.7.1 Ejemplo con XHTML
Un documento especifica transformaciones asociadas usando varias formas.
Por ejemplo un document XHTML puede contener lo siguiente:
<head profile="http://www.w3.org/2003/g/data-view
http://dublincore.org/documents/dcq-html/
http://gmpg.org/xfn/11">
<link rel="transformation" href="grokXFN.xsl" />
Código 3-2: Declaración de transformación GRDDL en XHTML
En el argumento “profile” se da a conocer que este documento tiene
transformación mediante GRDDL, en concreto en “http://www.w3.org/2003/g/data-view”.
La transformación se hará mediante el atributo “transformation” que apuntará a la hoja
XSL (en este caso grokXFN.xsl ) que marcará la forma en la que se extraerá la
información.
Cabe destacar que este código es valido para XHTML 1.x, ya que en HTML el
atributo “profile” ha sido eliminado.
3.7.2 Microformatos
Por otra parte, una página puede contener microformatos. Para ello, se
necesita un perfil (profile) específico que marcará la forma en la que se extraen datos
del documento.
Por ejemplo, un documento que tiene hcard mediante microformatos debería
de tener lo siguiente en su cabecera:
<head profile="http://www.w3.org/2003/g/data-view
http://www.w3.org/2006/03/hcard">
Código 3-3: Declaración de transformación GRDDL para hcard con Microformatos
Dentro de ese link a hcard tenemos:
<head profile="http://www.w3.org/2003/g/data-view">
3. CONCEPTOS BÁSICOS
28
Código 3-4: Profile de GRDDL dentro de hcard
Y por último:
<p>Use of this profile licenses RDF data extracted by
<a rel="profileTransformation"
href="../vcard/hcard2rdf.xsl">hcard2rdf.xsl</a>
from <a href="http://www.w3.org/2006/vcard/ns">the 2006
vCard/RDF work</a>.
</p>
Código 3-5: Datos de hcard conteninedo el XSL para transformar microformatos hcard en GRDDL
PROYECTO FIN DE CARRERA
29
4. JUSTIFICACIÓN
La realización de este proyecto está ligada a la necesidad de que cada vez
más páginas están convirtiéndose a páginas web semantizadas (es decir, páginas con
metadatos). A día de hoy, un gran porcentaje de páginas web tiene metadatos que a
simple vista el humano no puede ver sin usar herramientas externas, por ello una
solución sería la fácil extracción de metadatos.
4.1 BENEFICIOS TÉCNICOS
Los beneficios técnicos son bastante altos. En primer lugar debemos tener en
cuenta que necesitamos una extracción o introducción de metadatos. Eso aportaría un
valor en tiempo y esfuerzo. Por ejemplo, una empresa requiere un análisis de los RDF
que actualmente su página trata. Con el esta herramienta la visualización de esos
metadatos sería rápida y sin tener que hacer un despliegue grande de herramientas y
recursos.
Por otra parte, si una vez analizados los metadatos se quisiera realizar una
inserción de metadatos rápida, ésta se podría hacer mediante el propio servidor proxy
tras modificar su funcionamiento mediante un script. Esto permitiría ver los nuevos
metadatos en la página, pero sin embargo, no serían cambios definitivos. De esta
forma, podríamos pasar a hacerlos permanentes, haciendo las modificaciones
pertinentes en la página original y el servidor. Así la inserción de metadatos mediante
el servidor proxy se podría hacer como prueba antes de hacerlo definitivo.
Asimismo, como un efecto no orientado a la web semántica y ligado al cambio
de funcionamiento del servidor proxy mediante scripts, también se podría usar el proxy
para cambiar el aspecto e incluso el comportamiento de una página.
4.2 BENEFICIOS ECONÓMICOS
Los beneficios económicos no son tan claros como los técnicos. La herramienta
en sí, aportaría beneficio del tipo de ahorro en tiempo, herramientas y personal, que
traducido en términos económicos sería un ahorro alto al no tener que hacer uso de
esos recursos. A esto se le puede sumar que el aprendizaje de uso de la herramienta
es sencillo e intuitivo y no requiere mucha preparación para su manejo, por tanto, los
gastos derivados de la formación en el uso de la herramienta tampoco serían muy
altos.
PROYECTO FIN DE CARRERA
31
5. INVESTIGACIÓN EN TECNOLOGÍAS
5.1 VISIÓN GENERAL
En este capítulo se van a explicar las diferentes tecnologías utilizadas en el
desarrollo del Proyecto, las cuales se expondrán de forma teórica y explicativa así
como algún ejemplo práctico de ellas.
5.2 RECURSOS PRINCIPALES
5.2.1 Python
Python es un lenguaje de programación, interpretado, rápido y flexible. Cada
año gana nuevos adeptos y es de los lenguajes más utilizados actualmente. Es un
lenguaje de alto nivel cuya filosofía hace hincapié en una sintaxis muy limpia y que
favorezca un código legible.
Se trata de un lenguaje de programación multiparadigma ya que soporta
orientación a objetos, programación imperativa y, en menor medida, programación
funcional. Es un lenguaje interpretado, usa tipado dinámico, es fuertemente tipado y
multiplataforma.
Es administrado por la Python Software Foundation. Posee una licencia de
código abierto, denominada Python Software Foundation License, que es compatible
con la Licencia pública general de GNU a partir de la versión 2.1.1, e incompatible en
ciertas versiones anteriores.
Ilustración 5-1: Logo de Python
5. INVESTIGACIÓN EN TECNOLOGÍAS
32
5.2.1.1 Tipos de datos
Los tipos de datos que existen en este lenguaje, estos se pueden resumir en la
siguiente tabla:
Tipo Clase Notas Ejemplo
str Cadena Inmutable 'Cadena'
unicode Cadena Versión Unicode de str u'Cadena'
list Secuencia Mutable, puede contener objetos
de diversos tipos [4.0, 'Cadena', True]
tuple Secuencia Inmutable, puede contener
objetos de diversos tipos (4.0, 'Cadena', True)
set Conjunto Mutable, sin orden, no contiene
duplicados
set([4.0, 'Cadena',
True])
frozenset Conjunto Inmutable, sin orden, no
contiene duplicados
frozenset([4.0,
'Cadena', True])
dict Mapping Grupo de pares clave:valor {'key1': 1.0, 'key2':
False}
int Número
entero
Precisión fija, convertido en long
en caso de overflow. 42
long Número
entero Precisión arbitraria
42L ó
456966786151987643L
float Número
decimal Coma flotante de doble precisión 3.1415927
bool Booleano Valor booleano verdadero o falso True o False
PROYECTO FIN DE CARRERA
33
5.2.1.2 Ejemplo práctico
A modo de ejemplo práctico, en las siguientes líneas se va a mostrar un
pequeño programa desarrollado en Python con su correspondiente resultado devuelto
por pantalla.
En primer lugar, un ejemplo de una función (que en este caso calcula el
factorial) escrita en este lenguaje podría ser el siguiente:
def factorial(x):
if x == 0:
return 1
else:
return x * factorial(x - 1)
Código 5-1: Ejemplo de una función en Python
Asimismo, Python al igual que muchos lenguajes de programación es orientado
a objetos. En el siguiente bloque de código, se declara una clase y luego se llama al
objeto:
class Test:
def __init__(self, x, y):
self._x = x
self._y = y
def _suma(self):
return self._x + self._y
def suma(self):
return self._suma()
Código 5-2: Ejemplo de una clase en Python
En el bloque de código que viene a continuación se pueden ver la combinación
de los dos ejemplos anteriores en un script (o programa) de Python. La función
factorial se encuentra en un archivo llamado factorial.py y la clase Test en un
archivo llamado pythonTestClass.py:
from pythonTestClass import Test
from factorial import factorial
t = Test(1,3)
x = t.suma()
print factorial(x)
5. INVESTIGACIÓN EN TECNOLOGÍAS
34
Código 5-3 Ejemplo de un script (programa) en Python
Finalmente, tras la ejecución del anterior bloque de código, en las siguientes
líneas se muestra el resultado obtenido por línea de comandos (Python es un lenguaje
interpretado y por tanto, los programas realizados en este lenguaje se podrían ejecutar
directamente escribiéndolos en la línea de comandos propia de Python, no siendo
necesaria la escritura de un script/programa (fichero), pese a que esto último sea lo
más común.)
slok@sLoKPC:pythonPFCDoc$ python ./test.py
11
24
Código 5-4 Resultado del ejemplo anterior
5.2.1.3 Integración con el proyecto
En lo que a respecta al uso de Python dentro del proyecto, mencionar que todo
el código del proyecto ha sido escrito en este lenguaje. Es más, incluso el propio
código HTML del portal para el manejo del servidor proxy ha sido desarrollado
mediante Python, usando para ello el Framework de Desarrollo Django.
Las razones por las que se ha elegido este lenguaje de programación se
podrían resumir en varios puntos:
Es un lenguaje muy flexible.
El lenguaje es interpretado, por tanto, es fácil de poner en marcha.
Tiene muchas y muy buenas librerías incluidas (como cita un slogan de Python:
“¡Con baterías incluidas!”), además de existir una cantidad mayor de librerías
escritas por terceros.
Tiene gran cantidad de documentación de excelente calidad, algo que para el
aprendizaje y un buen desarrollo es muy importante.
La curva de aprendizaje es corta.
Cada vez se usa más este lenguaje.
Es de los lenguajes que más potencia tiene (o que se le puede sacar).
Su sintaxis es muy clara, ya que requiere que se tabule obligatoriamente.
Soporta objetos, clases abstractas, encapsulación…
Es una tecnología nueva para nosotros. Para el desarrollo del proyecto
decidimos utilizar algo nuevo que no supiéramos manejar de antemano (es
decir, que no hubiéramos visto a lo largo de la carrera), de modo que
constituiría una muy buena ocasión para aumentar nuestro conocimiento
(consideramos que el aprender nuevas cosas dentro del oficio de un Ingeniero
Informático, es algo importante).
Es multiplataforma
Es software libre
PROYECTO FIN DE CARRERA
35
5.2.2 Django
Después de haber elegido Python como lenguaje de programación para el
proyecto, era necesario elegir el framework con el que se iba a desarrollar el portal
web. Para Python existen muchas opciones principales:
Django
Web2Py
Pylons
Turbogears
WebPy
De todas ellas la elegida fue Django, por las siguientes razones:
Flexible, al igual que Python.
Tienen filtros que hacen muchos trabajos de manera automatizada.
Amplia documentación disponible.
Estable.
Muchas webs famosas lo usan.
Rápida puesta en marcha.
Funcionamiento excelente con servidores de producción (Apache, Nginx…).
Administrador de Django excelente (para la administración de usuarios,
grupos…).
Muy rápido.
Es multiplataforma (sobre python)
Es software libre.
Django es un framework de desarrollo web de código abierto, escrito en
Python, que cumple en cierta medida el paradigma del Modelo Vista Controlador
(MVC). Fue desarrollado en origen para gestionar varias páginas orientadas a noticias
de la World Company de Lawrence, Kansas, y fue liberada al público bajo una licencia
BSD en julio de 2005.
Ilustración 5-2: Logo Django
5. INVESTIGACIÓN EN TECNOLOGÍAS
36
La meta fundamental de Django es facilitar la creación de sitios web complejos.
Django pone énfasis en el re-uso, la conectividad y extensibilidad de componentes, el
desarrollo rápido y el principio “No te repitas” (DRY, del inglés Don't Repeat Yourself).
Python es usado en todas las partes del framework, incluso en configuraciones,
archivos, y en los modelos de datos.
5.2.2.1 Características
Entre las características/herramientas que dispone Django, aparte de las
previamente comentadas, existen muchas otras:
Un mapeador objeto-relacional.
Aplicaciones "enchufables" que pueden instalarse en cualquier página
gestionada con Django.
Una API de base de datos robusta.
Un sistema incorporado de "vistas genéricas" que ahorra tener que escribir la
lógica de ciertas tareas comunes.
Un sistema extensible de plantillas basado en etiquetas, con herencia de
plantillas.
Un despachador de URLs basado en expresiones regulares.
Un sistema middleware para desarrollar características adicionales; por
ejemplo, la distribución principal de Django incluye componentes middleware
que proporcionan cacheo, compresión de la salida, normalización de URLs,
protección CSRF y soporte de sesiones.
Soporte de internacionalización, incluyendo traducciones incorporadas de la
interfaz de administración.
Documentación incorporada accesible a través de la aplicación administrativa
(incluyendo documentación generada automáticamente de los modelos y las
bibliotecas de plantillas añadidas por las aplicaciones).
Pese a que Django se trata de un framework de Modelo Vista Controlador, en
realidad se caracteriza por otro nombre ya que difiere un poco de lo que comúnmente
se tiene en mente, aunque en el fondo sea lo mismo. Esta característica es una de las
que hace especial a Django sobre otros frameworks. Como cita la Wikipedia:
“Aunque Django está fuertemente inspirado en la filosofía de desarrollo Modelo
Vista Controlador, sus desarrolladores declaran públicamente que no se sienten
especialmente atados a observar estrictamente ningún paradigma particular, y en
cambio prefieren hacer "lo que les parece correcto". Como resultado, por ejemplo, lo
que se llamaría "controlador" en un "verdadero" framework MVC se llama en Django
"vista", y lo que se llamaría "vista" se llama "plantilla".
Gracias al poder de las capas mediator y foundation, Django permite que los
desarrolladores se dediquen a construir los objetos Entity y la lógica de presentación y
control para ellos.”
PROYECTO FIN DE CARRERA
37
Para poder usar Django, tan sólo es necesario tener instalado Python. Con
esto, Django podría funcionar perfectamente ya que trae consigo un servidor de
desarrollo (no apto para producción) y Sqlite3. En cuanto a otras BD, Django también
soporta MySQL, PostgreSQL y Oracle.
5.2.2.2 Funcionamiento
El flujo que sigue Django es algo particular. En la siguiente imagen y su
respectiva explicación se ve claramente cómo actúa Django:
1. El servidor que sirve la página creada con Django recibe la petición del cliente
2. Esta petición es mapeada con el URL Dispatcher (urls.py) y llama a las
funciones que sean necesarias (views.py) que previamente hayan sido
asignadas o si se tiene una versión cacheada, esta será la que se devolverá en
vez de llamar a la función.
3. Una vez se está ejecutando el código de la función definida en views.py se
suelen hacer operaciones de escritura y lectura en bases de datos (aunque en
ocasiones no se hace y se ejecutan otras acciones). Para ello los modelos de
la base de datos se especifican en models.py.
4. A continuación la vista lo último que hará será pasar el paquete HTTP que será
devuelto, para ello lo suele pasar los datos por la template o plantilla.
5. El/los paquete(s) se envía a su destinatario.
Ilustración 5-3: Flujo
5. INVESTIGACIÓN EN TECNOLOGÍAS
38
5.2.2.3 Estructura
La estructura de un proyecto de Django es muy limpia y flexible. Utiliza el
concepto de apps (aplicaciones) y proyectos de diferente forma. En otros frameworks
significan lo mismo, pero para Django una aplicación y un proyecto no son lo mismo.
Un proyecto contiene muchas aplicaciones, esas aplicaciones son reutilizables en
otros proyectos y por eso tienen sus propios archivos de mapeadores de URL, vistas
(funciones), modelos de base de datos, etc. aparte de los del proyecto en sí. Por
ejemplo, puede haber dos archivos urls.py: uno el del proyecto y otro el de una
aplicación dentro del proyecto.
En la imagen que se muestra a continuación se ve claramente la estructura de
un proyecto de Django (la imagen pertenece al explorador de archivos que trae el IDE
Eclipse):
Una explicación a la imagen superior:
La raíz del proyecto es simple_django (dentro del directorio /src). Ésta
contiene un fichero llamado __init__.py que es necesario por toda
aplicación de Python (para poder ejecutarlo) y puesto que Django está
completamente hecho en Python, éste también lo necesita.
El fichero manage.py que será con el que se interactuará para poder arrancar
la aplicación (servidor de desarrollo), crear la estructura de base de datos en la
base de datos, etc.
Settings.py contendrá toda la configuración del proyecto. Este fichero
contiene cosas tales como las rutas hacia las plantillas o templates, la ruta al
contenido estático (imágenes, sonidos, JavaScript…), la zona horaria,
contraseña de la base de datos etc.
Urls.py será el mapeador donde se especificará hacia donde tendrá que ir
Django después de recibir una petición con una determinada URL. Un ejemplo
de este archivo sería el siguiente:
Ilustración 5-4: Estructura de un proyecto en Django
PROYECTO FIN DE CARRERA
39
from django.conf.urls.defaults import *
urlpatterns = patterns('',
(r'^articles/2003/$', 'news.views.special_case_2003'),
(r'^articles/(\d{4})/$', 'news.views.year_archive'),
(r'^articles/(\d{4})/(\d{2})/$',
'news.views.month_archive'),
(r'^articles/(\d{4})/(\d{2})/(\d+)/$',
'news.views.article_detail'),
)
Código 5-5: Ejemplo de fichero urls.py
En el código de arriba podemos observar el contenido de un fichero
urls.py. Todos los ficheros de Django están escritos en Python puro y por
ello aprovechan la potencia de este lenguaje (como en este caso, que se hace
uso de las expresiones regulares de Python. Lo más importante de este archivo
es la estructura que tiene el mapeador de URL, que no es más que una tupla
compuesta por la expresión regular de la URL y la función a la que se llamará
después.
Simple_app es una aplicación. Anteriormente se ha comentado que un
proyecto de Django está compuesto por varias aplicaciones (en este caso, una
tan sólo). Una aplicación de Django puede prácticamente tener los mismos
archivos que un proyecto de Django, salvo excepciones como puede ser
manage.py.
Models.py tiene los modelos/esquemas que se almacenaran en la base de
datos. Un ejemplo de este archivo:
from django.db import models
class Person(models.Model):
first_name = models.CharField(max_length=30)
last_name = models.CharField(max_length=30)
Código 5-6: Ejemplo models.py
El código anterior se podría traducir en lenguaje SQL a lo siguiente:
CREATE TABLE myapp_person (
"id" serial NOT NULL PRIMARY KEY,
"first_name" varchar(30) NOT NULL,
"last_name" varchar(30) NOT NULL
);
Código 5-7: Traducción SQL de models.py
5. INVESTIGACIÓN EN TECNOLOGÍAS
40
Views.py es donde están los métodos a los que urls.py redirigirá tras
mapear la URL con la petición del cliente.
from django.shortcuts import get_object_or_404,
render_to_response
from django.http import HttpResponseRedirect, HttpResponse
from django.core.urlresolvers import reverse
from django.template import RequestContext
from polls.models import Choice, Poll
# ...
def vote(request, poll_id):
p = get_object_or_404(Poll, pk=poll_id)
try:
selected_choice =
p.choice_set.get(pk=request.POST['choice'])
except (KeyError, Choice.DoesNotExist):
# Redisplay the poll voting form.
return render_to_response('polls/detail.html', {
'poll': p,
'error_message': "You didn't select a choice.",
}, context_instance=RequestContext(request))
else:
selected_choice.votes += 1
selected_choice.save()
# Always return an HttpResponseRedirect after
successfully dealing
# with POST data. This prevents data from being posted
twice if a
# user hits the Back button.
return
HttpResponseRedirect(reverse('polls.views.results',
args=(p.id,)))
Código 5-8: Ejemplo de views.py
Como se puede observar, no es más que una función en lenguaje
Python que tras finalizar el método tendrá que llamar a otro método de Django
(HttpResponseRedirect), el cual hará lo necesario para la creación del
paquete HTTP, el template (plantilla), etc.
Todo proyecto de Django, salvo algunas pocas excepciones, puede ser
configurado para que no haga falta usar los nombres como views.py,
urls.py, etc. Sin embargo, es una convención usar estos nombres para
facilitar tanto el desarrollo como la lectura de código/proyecto.
5.2.3 Django-Revproxy
Previamente se ha mencionado como los proyectos y las aplicaciones tienen
especial diferencia en Django. Django-Revproxy es una aplicación para Django que
PROYECTO FIN DE CARRERA
41
hace que Django actúe como un proxy además de su funcionalidad como backend o
debugging tool para los metadatos y administración del proxy.
5.2.3.1 Funcionamiento
Django-Revproxy hace que Django pueda actuar como proxy frente a una
página. Por ejemplo, si se manda una petición a Django de una página previamente
registrada en Django, Django-Revproxy obtendrá esa página que se ha solicitado y a
continuación la enviará al cliente a través de Django. En la imagen que se muestra a
continuación se puede observar el comportamiento.
1. El cliente hace una petición a Django.
2. Django mira a ver si tiene esa dirección para poder hacer de proxy.
3. Si tiene esa dirección la pide al servidor original (que en este ejemplo se trata
de google.com).
4. Google devuelve la página original.
5. El servidor Django trata la página original devuelta.
6. Por último, Django devuelve la página original tratada por el proxy al cliente.
Por tanto, como se puede apreciar claramente, este comportamiento
corresponde al de un funcionamiento normal de un proxy.
5.2.3.2 Dependencias
Django-Revproxy tiene las siguientes dependencias:
Python (>= 2.5)
Django (>=1.2)
Ilustración 5-5: Flujo de Django-Revproxy
5. INVESTIGACIÓN EN TECNOLOGÍAS
42
Restkit (>=3.1)
5.2.3.3 Configuración
Para configurar Django-Revproxy se deben modificar algunos ficheros. En
primer lugar se debe editar el fichero settings.py que viene en la raíz del proyecto
de Django. Es en este fichero donde se asignarán las direcciones de las páginas que
el proxy podrá aceptar y hacer de proxy de ellas.
REVPROXY_SETTINGS = [
("_google", "http://google.com"),
("_friendpaste", "http://www.friendpaste.com"),
("_couchdb", "http://127.0.0.1:5984"),
]
Código 5-9: Asignación de direcciones proxy
También se deben editar las URLs en el archivo urls.py. Es aquí donde se
asignará como se accederá a las páginas aceptadas por el proxy.
from django.conf.urls.defaults import *
import revproxy.proxy
urlpatterns = patterns('',
(r'^proxy/', include(proxy.site_proxy.urls)),
)
Código 5-10: Asignación de urls en Django
5.2.3.4 Información adicional
El proyecto Django-Revproxy es software libre y está alojado en Github.com en
un repositorio del cual se ha hecho un fork y posteriormente añadido a la aplicación:
https://github.com/benoitc/dj-revproxy
La estructura de la aplicación Django-Revproxy es la que muestra la siguiente
imagen:
PROYECTO FIN DE CARRERA
43
5.2.3.5 Integración con el proyecto
Actualmente nuestro proyecto sólo contiene la carpeta /revproxy que está en
la raíz del proyecto dj-revproxy, ya que la aplicación de Django-Revproxy en sí
está contenida en dicha carpeta. Lo demás son simplemente ejemplos y ayudas para
poder instalar el proyecto Django-Revproxy en el sistema (nuestro proyecto lo trae
incluido, por tanto no es necesaria su instalación en el sistema).
5.2.4 Redland
Para la parte semántica se eligió la librería Redland. Pese a que no es nativo
de Python como otras librerías, ésta trae consigo unas bindings para Python que
hacen su uso posible con dicho lenguaje. Las razones por las que se eligió son
diversas:
Muy completo.
API muy limpia.
Flexible.
Amplia documentación.
Soporta muchos formatos de entrada y salida en lo que a la semántica se
refiere.
Software libre.
Redland es un conjunto de bibliotecas de software libre escrito en C que
proporcionan apoyo para el Resource Description Framework (RDF), la librería fue
creada hace unos años por Dave Beckett (un ex residente de Redland, Bristol).
Actualmente la librería o el framework, más concretamente, sigue muy activo y recibe
contribuciones de muchos lugares del mundo.
Ilustración 5-6: Carpetas y archivos de Revproxy
5. INVESTIGACIÓN EN TECNOLOGÍAS
44
Este framework semántico está compuesto por varias librerías o componentes
a su vez:
Raptor
RaSQaL
Redland (LibRDF)
Redland bindings
5.2.4.1 Raptor
Raptor es el componente de Redland encargado de parsear (analizar) y
serializar (cambiar el tipo de dato). Algunas características importantes de Raptor son
las siguientes:
Está diseñado para integrarse con Redland.
Puede parsear archivos desde webs y desde archivos locales.
Soporta todos los términos existentes de RDF incluidos en los XML.
Los parsers y los serializers pueden ser configurados en tiempo real.
Tiene bindings para los lenguajes Perl, PHP, Python and Ruby cuando se usa
con Redland.
No tiene fugas de memoria (memory leaks).
Es rápido.
Tiene una aplicación standalone (o que funciona sola) llamada Rapper para
parsear y serializar RDFs.
Sin embargo, pese a todas estas características, hay que mencionar que no
soporta todo tipo de documentos ni tipos. Aun así soporta muchos de los existentes.
5.2.4.1.1 Parsers
Los parsers son elementos que analizan documentos para después poder
ejecutar acciones con los datos extraídos de esos documentos. Para ello, Raptor debe
conocer la sintaxis en los que han sido escritos. A continuación se muestran los
parsers que tiene Raptor. Cada uno tiene un código de ejemplo de la sintaxis usada
por el tipo de “lenguaje”.
RDF/XML parser
<?xml version="1.0" encoding="utf-8"?>
<rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-
ns#"
xmlns:dc="http://purl.org/dc/elements/1.1/">
<rdf:Description rdf:about="http://www.w3.org/TR/rdf-syntax-
grammar">
<dc:title>RDF/XML Syntax Specification
(Revised)</dc:title>
PROYECTO FIN DE CARRERA
45
<dc:title xml:lang="en">RDF/XML Syntax Specification
(Revised)</dc:title>
<dc:title xml:lang="en-US">RDF/XML Syntax Specification
(Revised)</dc:title>
</rdf:Description>
<rdf:Description rdf:about="http://example.org/buecher/baum"
xml:lang="de">
<dc:title>Der Baum</dc:title>
<dc:description>Das Buch ist
außergewöhnlich</dc:description>
<dc:title xml:lang="en">The Tree</dc:title>
</rdf:Description>
</rdf:RDF>
Código 5-11: Ejemplo RDF/XML
N-Quads parser
<http://www.michelemostarda.com/foaf.rdf#me>
<http://xmlns.com/foaf/0.1/workplaceHomepage>
<http://www.fbk.eu> <http://www.michelemostarda.com/foaf.rdf>
.
<http://www.michelemostarda.com/foaf.rdf#me>
<http://xmlns.com/foaf/0.1/workInfoHomepage>
<http://www.michelemostarda.com/work.html>
<http://www.michelemostarda.com/foaf.rdf> .
<http://www.michelemostarda.com/foaf.rdf#me>
<http://xmlns.com/foaf/0.1/knows> _:node15v04bhrfx709971
<http://www.michelemostarda.com/foaf.rdf> .
Código 5-12: Ejemplo N-Quads
N-Triples parser
<http://www.w3.org/2001/sw/RDFCore/ntriples/>
<http://purl.org/dc/elements/1.1/creator> "Dave Beckett" .
<http://www.w3.org/2001/sw/RDFCore/ntriples/>
<http://purl.org/dc/elements/1.1/creator> "Art Barstow" .
<http://www.w3.org/2001/sw/RDFCore/ntriples/>
<http://purl.org/dc/elements/1.1/publisher>
<http://www.w3.org/> .
Código 5-13: Ejemplo N-Triples
5. INVESTIGACIÓN EN TECNOLOGÍAS
46
Turtle parser
@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
@prefix dc: <http://purl.org/dc/elements/1.1/> .
@prefix ex: <http://example.org/stuff/1.0/> .
<http://www.w3.org/TR/rdf-syntax-grammar>
dc:title "RDF/XML Syntax Specification (Revised)" ;
ex:editor [
ex:fullname "Dave Beckett";
ex:homePage <http://purl.org/net/dajobe/>
] .
Código 5-14: Ejemplo Turtle
TRiG parser
# TriG Example Document 2
@prefix ex: <http://www.example.org/vocabulary#> .
@prefix : <http://www.example.org/exampleDocument#> .
:G1 = { :Monica a ex:Person ;
ex:name "Monica Murphy" ;
ex:homepage <http://www.monicamurphy.org> ;
ex:email <mailto:[email protected]> ;
ex:hasSkill ex:Management ,
ex:Programming . } .
Código 5-15: Ejemplo TRiG
Rss “Tag Soup” parser
<?xml version="1.0"?>
<rdf:RDF
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns="http://purl.org/rss/1.0/"
>
<channel rdf:about="http://www.xml.com/xml/news.rss">
<title>XML.com</title>
<link>http://xml.com/pub</link>
<description>
XML.com features a rich mix of information and services
for the XML community.
</description>
PROYECTO FIN DE CARRERA
47
<image
rdf:resource="http://xml.com/universal/images/xml_tiny.gif" />
<items>
<rdf:Seq>
<rdf:li
resource="http://xml.com/pub/2000/08/09/xslt/xslt.html" />
<rdf:li
resource="http://xml.com/pub/2000/08/09/rdfdb/index.html" />
</rdf:Seq>
</items>
<textinput rdf:resource="http://search.xml.com" />
</channel>
</rdf:RDF>
Código 5-16: Ejemplo RSS (con RDF)
GRDDL y microformatos parser
<?xml version="1.0" encoding="UTF-8"?>
<html xmlns="http://www.w3.org/1999/xhtml"
xml:base="http://www.dc4plus.com/references/rdf_sem.html"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:foaf="http://xmlns.com/foaf/0.1/" >
<head profile="http://ns.inria.fr/grddl/rdfa/">
<title>Biblio description</title>
</head>
<body>
<h1>Biblio description</h1>
<dl about="http://www.w3.org/TR/2004/REC-rdf-mt-20040210/">
<dt>Title</dt>
<dd property="dc:title">RDF Semantics - W3C
Recommendation 10 February 2004</dd>
<dt>Author</dt>
<dd rel="dc:creator" href="#a1">
<span id="a1">
<link rel="rdf:type" href="[foaf:Person]" />
<span property="foaf:name">Patrick Hayes</span>
see <a rel="foaf:homepage"
href="http://www.ihmc.us/users/user.php?UserID=42">homepage</a>
</span>
</dd>
</dl>
</body>
</html>
Código 5-17: Ejemplo GRDDL (Sobre HTML)
5. INVESTIGACIÓN EN TECNOLOGÍAS
48
RDFa parser
<p xmlns:dc="http://purl.org/dc/elements/1.1/"
about="http://www.example.com/books/wikinomics">
In his latest book
<em property="dc:title">Wikinomics</em>,
<span property="dc:creator">Don Tapscott</span>
explains deep changes in technology,
demographics and business.
The book is due to be published in
<span property="dc:date" content="2006-10-01">October
2006</span>.
</p>
Código 5-18: Ejemplo RDFa (Sobre HTML)
5.2.4.1.2 Serializers
Los serializers o serializadores tratan de modificar el tipo de salida. De esta
forma se puede parsear (analizar) un documento y después serializarlo a otro formato
directamente o después de haber hecho alguna acción sobre los datos guardarlos en
un formato determinado. Muchos de estos formatos (por no decir casi todos) son los
mismos que los parsers. A continuación se muestran los diferentes serializadores de
Raptor así como un código de ejemplo de la sintaxis usada por el tipo de “lenguaje”
serializado por estos (en este caso, sólo contienen el ejemplo de código aquellos que
sean diferentes de los ya enseñados en los parsers previamente descritos).
Serializador RDF/XML
Serializador N-QUADS
Serializador N-Triples
Serializador Atom 1.0
<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
<title>Example Feed</title>
<subtitle>A subtitle.</subtitle>
<link href="http://example.org/feed/" rel="self" />
<link href="http://example.org/" />
<id>urn:uuid:60a76c80-d399-11d9-b91C-0003939e0af6</id>
<updated>2003-12-13T18:30:02Z</updated>
<author>
<name>John Doe</name>
<email>[email protected]</email>
</author>
<entry>
<title>Atom-Powered Robots Run Amok</title>
PROYECTO FIN DE CARRERA
49
<link
href="http://example.org/2003/12/13/atom03" />
<link rel="alternate" type="text/html"
href="http://example.org/2003/12/13/atom03.html"/>
<link rel="edit"
href="http://example.org/2003/12/13/atom03/edit"/>
<id>urn:uuid:1225c695-cfb8-4ebb-aaaa-
80da344efa6a</id>
<updated>2003-12-13T18:30:02Z</updated>
<summary>Some text.</summary>
</entry>
</feed>
Código 5-19: Ejemplo Atom 1.0
Serializador Json
{"menu": {
"id": "file",
"value": "File",
"popup": {
"menuitem": [
{"value": "New", "onclick": "CreateNewDoc()"},
{"value": "Open", "onclick": "OpenDoc()"},
{"value": "Close", "onclick": "CloseDoc()"}
]
}
}}
Código 5-20: Ejemplo Json
Serializador Graphviz DOT (Usado para grafos)
graph ethane {
C_0 -- H_0 [type=s];
C_0 -- H_1 [type=s];
C_0 -- H_2 [type=s];
C_0 -- C_1 [type=s];
C_1 -- H_3 [type=s];
C_1 -- H_4 [type=s];
C_1 -- H_5 [type=s];
}
Código 5-21: Ejemplo DOT (Grafos)
Serializador RSS 1.0
Serializador Turtle
5. INVESTIGACIÓN EN TECNOLOGÍAS
50
Serializador XMP (compatible haciendo uso de RDF/XML)
5.2.4.2 Rasqal
Rasqal es el componente de Redland que se encarga de todo lo que tiene que
ver con las consultas en la base de datos semántica.
Esta herramienta tiene las siguientes características:
Una API para el acceso y construcción de consultas RDF.
Soporte para el lenguaje de consultas SPARQL 1.0 y partes de SPARQL 1.1.
Soporte para el lenguaje de consultas RDQL 1.0.
Un mecanismo de ejecución de consultas que agrupa, agrega expresiones y
evaluación por filtros.
Una binding API para los resultados de consultas.
Puede dar los resultados de consultas en diferentes formatos:
o SPARQL XML
o SPARQL JSON
o CSV
o TSV
o HTML
o Tablas ASCII
o RDF/XML
o Turtle / N3
No tiene fugas de memoria (memory leaks).
Tiene una aplicación standalone (o que funciona sola) llamada Roquet.
5.2.4.3 Redland (LibRDF)
Redland o LibRDF es la librería que hace que las demás librerías o
componentes funcionen en conjunto. Además de ello, tiene las siguientes
características:
Librerías modulares y basadas en objetos para la manipulación de triples,
grafos RDF, URIs y literales.
Guardado de grafos (tipo RDF, no gráficos) compatible con:
o Oracle Berkeley DB
o MySQL 3-5
o PostgreSQL
o Openlink Virtuoso
o SQLite
o Archivos
o URIs
Soporte de diferentes sintaxis en lectura y escritura (vía Raptor).
Soporte de consultas en diferentes sintaxis (via RaSQaL).
PROYECTO FIN DE CARRERA
51
Soporte de diferentes lenguajes (via Bindings).
Utilidades:
o Rdfproc (RDF)
o Rapper (Parsing)
o Roqet (Query)
Portable.
Rápido.
Sin fugas de memoria (memory leaks).
Redland, al igual que todas sus librerías, son software libre. Están licenciadas
sobre LGPL 2.1, GPL 2 o Apache 2 dependiendo de cada componente.
5.2.4.4 Bindings
La librería Redland tiene bindings para diferentes lenguajes. Para este proyecto
tan sólo se ha usado las bindings de Python. Sin embargo Redland también está
disponible para estos lenguajes:
Lua (experimental)
Perl
PHP
Python
Ruby
5.2.5 Git
Este proyecto ha sido elaborado por dos personas, por ello desde el comienzo
se ha usado un control de versiones. El control de versiones es conveniente para el
desarrollo, ya que permite llevar un orden y mantener un control del mismo en todo
momento.
Como controles de versiones existen varios donde elegir:
CVS
SVN
Bazaar
Ilustración 5-7: Logo Git
5. INVESTIGACIÓN EN TECNOLOGÍAS
52
Mercurial
Trac
Git
Algunos de ellos son antiguos y otros, a pesar de no ser tan antiguos, son
centralizados. Un buen control de versiones debería de ser distribuido. Para este
proyecto el control de versiones elegido ha sido Git por las siguientes razones:
Flexible.
Rápido.
Estable.
Distribuido.
Muchas características (tiene infinidad de posibilidades que otros SCV
carecen).
Software libre.
Multiplataforma.
Nuevo para nosotros (al igual que con Python y Django, para el control de
versiones quisimos probar una nueva herramienta que no conociéramos de
antemano).
Git es un software de control de versiones diseñado por Linus Torvalds
(creador del kernel Linux), pensando en la eficiencia y la confiabilidad del
mantenimiento de versiones de aplicaciones cuando estas tienen un gran número de
archivos de código fuente.
Hay algunos proyectos de mucha relevancia que hacen uso de este software
de control de versiones:
Kernel Linux
QT
Django
Ruby on Rails
Yahoo
Gnome
KDE
Android
Debian
Git
Eclipse
…
PROYECTO FIN DE CARRERA
53
El diseño de Git se basó en BitKeeper y en Monotone. Resulta de la
experiencia del diseñador de Linux, Linus Torvalds, manteniendo una enorme cantidad
de código distribuida y gestionada por mucha gente, que incide en numerosos detalles
de rendimiento, y de la necesidad de rapidez en una primera implementación.
Entre las características más relevantes de Git se encuentran:
Fuerte apoyo al desarrollo no-lineal, por ende rapidez en la gestión de
ramificaciones y mezclado de diferentes versiones. Git incluye herramientas
específicas para navegar y visualizar un historial de desarrollo no-lineal. Una
presunción medular en Git es que un cambio será fusionado o empalmado
mucho más frecuentemente de lo que se escribe originalmente, conforme se
pasa entre varios programadores que lo revisan.
Gestión distribuida. Al igual que Darcs, BitKeeper, Mercurial, SVK, Bazaar y
Monotone, Git le da a cada programador una copia local del historial del
desarrollo entero, y los cambios se propagan entre los repositorios locales. Los
cambios se importan como ramificaciones adicionales y pueden ser fusionados
en la misma manera que se hace con la ramificación local.
Los almacenes de información pueden publicarse por HTTP, FTP, rsync o
mediante un protocolo nativo, ya sea a través de una conexión TCP/IP simple o
a través de cifrado SSH. Git también puede emular servidores CVS, lo que
habilita el uso de clientes CVS pre-existentes y modulos IDE para CVS pre-
existentes en el acceso de repositorios Git.
Los repositorios Subversion y svk se pueden usar directamente con git-svn.
Gestión eficiente de proyectos grandes, dada la rapidez de gestión de
diferencias entre archivos, entre otras mejoras de optimización de velocidad de
ejecución.
Todas las versiones previas a un cambio determinado, implican la notificación
de un cambio posterior en cualquiera de ellas a ese cambio (denominado
autenticación criptográfica de historial).
Resulta algo más caro trabajar con ficheros concretos frente a proyectos. Eso
diferencia el trabajo frente a CVS, que trabaja con base en cambios de fichero,
pero mejora el trabajo con afectaciones de código que concurren en
operaciones similares en varios archivos.
Los renombrados se trabajan basándose en similitudes entre ficheros, aparte
de nombres de ficheros, pero no se hacen marcas explícitas de cambios de
nombre con base en supuestos nombres únicos de nodos de sistema de
ficheros, lo que evita posibles, y posiblemente desastrosas, coincidencias de
ficheros diferentes en un único nombre.
Realmacenamiento periódico en paquetes (ficheros). Esto es relativamente
eficiente para escritura de cambios y relativamente ineficiente para lectura si el
reempaquetado (con base en diferencias) no ocurre cada cierto tiempo.
Como todo control de versiones, Git tiene sus propias herramientas para poder
trabajar con él y poder gestionar los repositorios y proyectos. Existen de varios tipos:
5. INVESTIGACIÓN EN TECNOLOGÍAS
54
Línea de comandos
Gráficas
Graficas de IDE
Por defecto, siempre se suele usar la de línea de comandos (como es el caso
de nuestro proyecto), pero también existen plug-ins para IDEs como Eclipse (egit) para
implementar las funcionalidades. Por otro lado, con el entorno oficial de trabajo (la
línea de comandos) viene también una aplicación llamada gitk que es una herramienta
gráfica que permite visualizar las diferencias entre revisiones así como también
proporciona información de los commits realizados (por ejemplo, el hash sha1, autor,
hora…).
Como se ve en la imagen anterior, Git no trabaja como los demás controles de
versión ya que dispone de un estado intermedio entre el “commit” en el repositorio y el
directorio de trabajo. Esto facilita la forma en la que se van guardando los cambios.
Previamente se ha comentado que Git está preparado para trabajar con ramas.
En este aspecto Git es de lo mejor que existe actualmente, ya que es muy fácil
mezclar (merge) y crear ramas. Esta característica ha resultado importante en la
realización del proyecto, ya que se han mantenido dos ramas durante todo el
desarrollo: la rama principal de nombre “master” (nombre por defecto de la rama
principal en un repositorio Git) y una segunda rama de nombre “experimental”.
Asimismo, durante el desarrollo de han ido saliendo a su vez otras ramas que
posteriormente se han unido a alguna de las mencionadas ramas.
Ilustración 5-8: Estados de trabajo con Git
PROYECTO FIN DE CARRERA
55
En la imagen superior se puede apreciar un bloque de “commits” y las ramas
en las que han sido realizados, así como las distintas fusiones o merges entre ramas y
las creaciones de éstas. Este gráfico ha sido obtenido con la herramienta gitk.
La web del proyecto y sus herramientas están disponibles en: http://git-
scm.com/
5.2.5.1 Github
Al ser un sistema de control distribuido, Git también puede funcionar como
repositorio local. No obstante, usar un repositorio remoto es más recomendable sobre
todo si se trata de un proyecto en el que colaboran distintas personas de distintos
Ilustración 5-9: Commits y branchs del proyecto visualizados en gitk
Ilustración 5-10: Logo Github
5. INVESTIGACIÓN EN TECNOLOGÍAS
56
lugares, ya que permiten un mejor y más sencillo acceso al él. Para ello existen
algunas alternativas de las cuales las principales son:
Gitorious
Github
Para el proyecto, se decidió utilizar Github a pesar de que ambas constituyen
excelentes alternativas.
En la siguiente imagen se puede apreciar la interfaz de Github del proyecto
actual que se encuentra hospedado en dicha página y cuya dirección es:
https://github.com/slok/metaproxy
Actualmente existen diversos manuales (tanto en internet como en forma de
libro) de cómo usar Git. Uno de los libros más famosos y más recomendables para
aprender a usar Git, Progit (también disponible online en la dirección:
http://progit.org/book/) fue escrito por uno de los desarrolladores de Github (Scott
Chacon).
Ilustración 5-11: Proyecto hospedado en Github
PROYECTO FIN DE CARRERA
57
Por otro lado, Github ofrece claridad, comodidad y muchas facilidades para el
desarrollo de proyectos. Una de ellas es que Github ofrece la posibilidad de ver las
ramas existentes en el repositorio de un proyecto directamente en el navegador con la
información del repositorio online (es decir, algo parecido a lo que ofrece gitk sólo que
online).
5.3 RECURSOS
5.3.1 Restkit
Restkit ( http://benoitc.github.com/restkit/ ) es un kit de recursos HTTP para python,
Con restkit se pueden construir objetos entorno a HTTP e interactuar con ellos de
forma sencilla además es la base de couchkit un kit para couchDB en python.
Además este kit es de los mismos desarrolladores de revproxy y por tanto revproxy
ahce uso de el. Por ello Restkit es una dependencia necesaria para dj-revproxy.
En este poryecto se ha tenido que estudiar parte de la API de restkit y de la forma en
la que se desarrolla con ello, esto es debido a que para modificar el comportamiento
de revproxy se necesitaban conocimientos de este recurso.
Sus características principales son:
Cliente HTTP compatible con HTTP 1.0 y 1.1
Threadsafe (Seguridad en hilos)
Ilustración 5-12: Branchs del proyecto en Github
5. INVESTIGACIÓN EN TECNOLOGÍAS
58
Usa llamadas de socket puras y tiene su propio parseador de HTTP (no está
basado en urllib2 ni httplib)
Mapea recursos http a objetos de Python
Lee y envía en tiempo real (on the fly)
Reutiliza las conexiones
Soporte para eventlet y gevent
Soporte para transferencia por bloques codificados en ambos sentidos
Soporte para autenticación básica y OAuth
Se hace cargo de los proxys
Filtros HTTP
Compatible con python 2.x (>= 2.5)
A modo de ejemplos sencillos (obtener información de una página):
>>> from restkit import request
>>> r =
request('http://friendpaste.com/1ZSEoJeOarc3ULexzWOk5Y_633433316631/r
aw')
>>> r.body_string()
'welcome to friendpaste'
>>> r.headers
{'status': '200 OK', 'transfer-encoding': 'chunked', 'set-cookie':
'FRIENDPASTE_SID=b581975029d689119d3e89416e4c2f6480a65d96;
expires=Sun,
14-Mar-2010 03:29:31 GMT; Max-Age=1209600; Path=/', 'server':
'nginx/0.7.62',
'connection': 'keep-alive', 'date': 'Sun, 28 Feb 2010 03:29:31 GMT',
'content-type': 'text/plain'}
Código 5-22: Ejemplo 1º de uso básico con restkit
Algo parecido pero utilizando objetos de python directamente:
>>> from restkit import Resource
>>> res = Resource('http://friendpaste.com')
>>> r = res.get('/1ZSEoJeOarc3ULexzWOk5Y_633433316631/raw')
>>> r.body_string()
'welcome to friendpaste'
Código 5-23: Ejemplo 2º de uso básico con restkit
5.3.2 LXML
LXML es una librería que no se ha usado directamente en el proyecto, sino que
alguna de las otras herramientas/librerías usadas dependía de ella para su correcto
funcionamiento.
PROYECTO FIN DE CARRERA
59
El kit de herramientas XML LXML es un binding de Python para las librerías
libxml2 y libxslt de C. Es el único que combina la velocidad y la integridad
característica XML de estas bibliotecas con la simplicidad de una API nativa de
Python, en su mayoría compatibles, pero superior a la conocida API ElementTree.
5.3.3 Pygments
Pygments es una librería muy famosa para el realzado y coloreado de sintaxis,
no sólo en el mundo de Python, sino que en otros muchos lenguajes.
Pygments es un realzador de sintaxis (Syntax highlighter) genérico para todo
tipo de programas, foros, wikis y otras aplicaciones que necesitan embellecer su
código fuente a la hora de visualizarlo.
Sus características más importantes son las siguientes:
Un gran número de lenguajes soportados.
Un gran número de estilos para el código.
Presta especial atención en los detalles con el fin de que su lectura sea clara.
El soporte para el añadido de nuevos lenguajes es fácil. Todo está hecho con
expresiones regulares.
Soporta varios formatos de salida, entre ellos: HTML, RTF, LaTeX y
secuencias ANSI.
Se puede usar como línea de comandos o librería.
Dentro del proyecto, Pygments se ha usado para el realce de la sintaxis de
código fuente en la página, tanto en la parte para mostrar los scripts almacenados en
el servidor proxy, como en los resultados XML obtenidos tras hacer queries SPARQL.
Gracias a Pygments, el código en general se ve más claro, lo que contribuye a que el
usuario lo entienda mejor.
5.3.4 Python Graph & Graphviz
A pesar de que las incluyamos en la misma sección, Python Graph y Graphviz
son dos cosas diferentes pero que están relacionadas entre sí. Y es que la primera es
un complemento independiente a la segunda.
Graphviz es un paquete de herramientas de código abierto iniciado por AT & T
Labs Research para la elaboración de los gráficos. Los gráficos se especifican en las
secuencias de comandos del lenguaje DOT. También proporciona bibliotecas para
aplicaciones de. Graphviz es un software libre bajo la Licencia Pública de Eclipse.
5. INVESTIGACIÓN EN TECNOLOGÍAS
60
Graphviz coge los gráficos en forma de texto escritos en un lenguaje simple y
crea diagramas en formatos útiles tales como imágenes (JPG, PNG…), SVG para
páginas web, PDF o Postscript para su inclusión en otros documentos. Asimismo,
también permite la posibilidad de mostrar los diagramas en un navegador gráfico
interactivo. Cabe mencionar que Graphviz también soporta GXL, un dialecto de XML.
Por otro lado, Graphviz tiene muchas funciones útiles para diagramas concretos, como
las opciones de colores, fuentes, los diseños de tablas de nodos, estilos de línea,
enlaces, etc.
A continuación se muestra un ejemplo simple de una representación de un
diagrama con Graphviz:
En forma de texto o código:
digraph G {
subgraph cluster_0 {
style=filled;
color=lightgrey;
node [style=filled,color=white];
a0 -> a1 -> a2 -> a3;
label = "process #1";
}
subgraph cluster_1 {
node [style=filled];
b0 -> b1 -> b2 -> b3;
label = "process #2";
color=blue
}
start -> a0;
start -> b0;
a1 -> b3;
b2 -> a3;
a3 -> a0;
a3 -> end;
b3 -> end;
start [shape=Mdiamond];
end [shape=Msquare];
}
Código 5-24: Ejemplo de lenguaje DOT en Graphviz
PROYECTO FIN DE CARRERA
61
Este código daría como resultado el siguiente grafo:
Por otro lado, en cuanto a Python Graph, ésta se trata de una librería para
trabajar con gráficos en Python. Este software proporciona un conjunto de algoritmos
importantes y una estructura de datos adecuada para la representación de gráficos.
Se suele utilizar junto a Graphviz para la creación de grafos en Python. De esta
forma usando Python Graph y las bindings de Python de Graphviz se tiene una amplia
gama de posibilidades sobre grafos dentro del lenguaje Python. Además, Python
Graph tiene una API muy extensa que incluye diferentes algoritmos, algunos de los
cuales son:
Búsqueda heurística: A*
MiniMax
Algoritmo de Prim
Algoritmo de Dijkstra
Algoritmo de Bellman-Ford
Esto es un ejemplo de cómo se crea un grafo con Python Graph junto a
Graphviz:
Ilustración 5-13: Grafo creado con Graphviz
5. INVESTIGACIÓN EN TECNOLOGÍAS
62
#!/usr/bin/env python
# Copyright (c) 2007-2008 Pedro Matiello <[email protected]>
# License: MIT (see COPYING file)
# Import graphviz
import sys
sys.path.append('..')
sys.path.append('/usr/lib/graphviz/python/')
sys.path.append('/usr/lib64/graphviz/python/')
import gv
# Import pygraph
from pygraph.classes.graph import graph
from pygraph.classes.digraph import digraph
from pygraph.algorithms.searching import breadth_first_search
from pygraph.readwrite.dot import write
# Graph creation
gr = graph()
# Add nodes and edges
gr.add_nodes(["Portugal","Spain","France","Germany","Belgium","Nethe
rlands","Italy"])
gr.add_nodes(["Switzerland","Austria","Denmark","Poland","Czech
Republic","Slovakia","Hungary"])
gr.add_nodes(["England","Ireland","Scotland","Wales"])
gr.add_edge(("Portugal", "Spain"))
gr.add_edge(("Spain","France"))
gr.add_edge(("France","Belgium"))
gr.add_edge(("France","Germany"))
gr.add_edge(("France","Italy"))
gr.add_edge(("Belgium","Netherlands"))
gr.add_edge(("Germany","Belgium"))
gr.add_edge(("Germany","Netherlands"))
gr.add_edge(("England","Wales"))
gr.add_edge(("England","Scotland"))
gr.add_edge(("Scotland","Wales"))
gr.add_edge(("Switzerland","Austria"))
gr.add_edge(("Switzerland","Germany"))
gr.add_edge(("Switzerland","France"))
gr.add_edge(("Switzerland","Italy"))
gr.add_edge(("Austria","Germany"))
gr.add_edge(("Austria","Italy"))
gr.add_edge(("Austria","Czech Republic"))
gr.add_edge(("Austria","Slovakia"))
gr.add_edge(("Austria","Hungary"))
gr.add_edge(("Denmark","Germany"))
gr.add_edge(("Poland","Czech Republic"))
gr.add_edge(("Poland","Slovakia"))
gr.add_edge(("Poland","Germany"))
gr.add_edge(("Czech Republic","Slovakia"))
gr.add_edge(("Czech Republic","Germany"))
gr.add_edge(("Slovakia","Hungary"))
PROYECTO FIN DE CARRERA
63
# Draw as PNG
dot = write(gr)
gvv = gv.readstring(dot)
gv.layout(gvv,'dot')
gv.render(gvv,'png','europe.png'
Código 5-25: Código de ejemplo de Python Graph
Dentro del proyecto, Graphviz y Python Graph han sido usados para la
creación de grafos a partir de los RDFs que se extraen de páginas manejadas por el
servidor proxy.
5.3.5 Beautiful Soup
Beautiful Soup es un parser de XML/HTML escrito en Python que está
diseñado para que devuelva una respuesta rápida. Entre sus características más
importantes se encuentran:
Tiene métodos simples y claros para navegar, buscar y modificar a lo largo de
todo el árbol. De esta forma la extracción es fácil y no es necesario hacerse un
parser para cada aplicación.
No importa si el código está “roto”. Beautiful Soup crea un árbol similar al
original (es decir, el que debería de ser pero que por estar "roto" se encuentra
incompleto) y obtiene los datos necesarios de éste.
Beautiful Soup convierte el documento a UTF8 automáticamente, a menos que
se especifique lo contrarío o no se pueda detectar automáticamente la
codificación del documento parseado.
En este proyecto Beautiful Soup ha sido usado para analizar el HTML de
páginas que son obtenidas, para posteriormente devolverlas al cliente (hacer de
proxy).
PROYECTO FIN DE CARRERA
65
6. DESARROLLO
6.1 ESTRUCTURA DEL PROYECTO
En esta sección de la documentación se hablará sobre todo lo relacionado con
el desarrollo del proyecto. Hasta ahora se han explicado los diferentes recursos
usados sin hacer demasiado hincapié en lo que es el proyecto en sí, pese a que en
algún momento se ha explicado brevemente para qué se han usado ciertas librerías o
frameworks. Para explicar adecuadamente el desarrollo del proyecto a continuación,
éste se separará en dos bloques: la parte Web (portal web) por un lado y, por otro, la
parte más interna del proyecto.
6.1.1 Portal Web (Django)
Previamente se ha comentado que para
desarrollar la parte web del proyecto (el portal
web) se eligió el framework Django por las
razones ya mencionadas. En primer lugar se
empezará a explicar el desarrollo del proyecto
comenzando por la parte web (o gráfica) de
éste.
6.1.1.1 Estructura
En la imagen de la parte izquierda se
muestra la estructura del proyecto, la cual
corresponde con la típica estructura de un
proyecto de Django.
En primer lugar, podemos apreciar que
existen los típicos archivos de Django:
manager.py, urls.py, etc. (mencionados en
el punto 5.2.2.3 de la presente documentación)
necesarios en toda aplicación de Django.
En el directorio /static se encuentran
todas las imágenes que el proyecto necesita
para su parte visual gráfica, los JavaScript que
utiliza y en general, todo contenido estático
como son los uploads (subidas de archivos) Ilustración 6-1: Estructura del proyecto
6. DESARROLLO
66
realizados al servidor, o archivos temporales que se van creando.
El directorio /templates es el que contiene todos los HTML del portal web,
tanto de la página principal como de parte de los paneles de administración del
servidor proxy (incluido el login) y panel de administración de usuarios.
La carpeta /manager corresponde a una aplicación de Django1 que contiene
toda la estructura Django del panel de administración del servidor proxy, así como
también permite la configuración de éste.
De igual modo, la carpeta /pygmetize corresponde a otra aplicación de
Django que contiene los filtros para poder darle color a la sintaxis del código fuente.
Para ello se ha hecho uso de la librería Pygments como se ha comentado previamente
en el punto 5.3.2 de la presente documentación.
Por otro lado, el directorio /revproxy es el que contiene el núcleo del proxy,
ya que contiene la aplicación será la que hará que el servidor actúe como proxy
haciendo uso de Django para ello2.
En el directorio /scripts, como su propio nombre indica, se encuentran los
scripts que se ejecutarán sobre las páginas solicitadas por los clientes cuando se haga
uso del proxy. Estos scripts realizarán diferentes cambios (dependiendo de su
programación) sobre la página que se está redireccionando (haciendo de proxy).
Debido a la extensión del tema más adelante3 se explicará en más profundidad este
apartado.
Por último, en /utils se encuentran todas aquellas funciones creadas en
Python y donde se pueden incluir cualquier método adicional que se programe para
posteriormente hacer uso de él/ellos en los scripts. En este directorio es donde se
encuentra una gran parte de la API de este proyecto.
6.1.1.2 URLs
Una de las características más importantes de Django es que toda su sintaxis
de URLs es muy limpia y por tanto, no da lugar a URLs largas y complejas formadas
por muchos caracteres, números y símbolos seguidos. Los archivos de URLs que
tiene el proyecto son los siguientes:
urls.py
from django.conf.urls.defaults import *
from metaproxy.views import *
1 Ver punto 5.2.2.3 para más información acerca de la estructura de un proyecto en Django.
2 Ver punto 5.2.3 para más información acerca de la aplicación Django-Revproxy.
3 Ver punto 6.1.3 para más información acerca de los scripts.
PROYECTO FIN DE CARRERA
67
from django.contrib import admin
import manager
from manager.urls import *
from revproxy import proxy
admin.autodiscover()
urlpatterns = patterns('',
#proxied URLs
(r'^proxy/', include(proxy.site_proxy.urls)),
#main page (directly the proxy or a page with all the proxied
sites??)
(r'^$', main_page),
#login/logout
(r'^login/$', 'django.contrib.auth.views.login'),
(r'^logout/$', logout_page),
#admin
(r'^admin/', include(admin.site.urls)),
#manager
(r'^manager/', include(manager.urls)),
# Serve static content.
(r'^static/(?P<path>.*)$', 'django.views.static.serve',
{'document_root': 'static'}),
)
Código 6-1: urls.py
Como se puede observar en el código anterior, existen varias redirecciones
que se explicarán a continuación:
Main Page (Index): Esta es la URL que será la primera a la cual se
accederá.
Proxied URLs: Esta URL está formada a su vez por más URLs que serán
las que redirigirán a la función del proxy de cada página, es decir, a través
de ellas se accederá al proxy de la página solicitada (página similar a la
original pero ligeramente modificada por los scripts introducidos). Su URL
será: http://xxxxxx.xxx/proxy/xxxx
Login/Logout: Estas URLs redirigirán a las funciones de ingresar y salir
con un determinado usuario en el administrador del proxy denominado
Manager4.
Admin: Admin es la URL por la cual se accederá al panel de administración
de Django5, encargado de tareas como la administración de usuarios.
Manager: Aquí está el panel de administración del servidor proxy. Su URL
será: http://xxxxxx.xxx/manager/xxxx
4 Ver punto 6.1.1.4 para más información sobre el Manager.
5 Ver punto 6.1.1.4 para más información sobre el administrador de Django.
6. DESARROLLO
68
Static: Permite poder acceder al contenido estático como CSS, JavaScript,
imágenes, etc.
Manager/urls.py
from django.conf.urls.defaults import *
from manager.views import *
urlpatterns = patterns('',
# Main web entrance.
(r'^$', manager_main_page),
(r'^rdf/$', manager_rdf_upload_page),
(r'^ontologies/$', manager_ontologies_page),
(r'^sparql/$', manager_sparql_queries_page),
(r'^scripts/$', manager_scripts_page),
(r'^scripts/(?P<id>\w+)/$', manager_scripts_code_page),
(r'^addweb/$', manager_addweb_page),
(r'^addweb/(?P<id>\w+)/$', manager_addweb_delete_page),
)
Código 6-2: manager/urls.py
Como se puede apreciar, desde manager/urls.py se redirige a
varias páginas que se explicarán más adelante en el punto 6.1.1.4.
6.1.1.3 Administración de Django
Antes de pasar a explicar la parte del proyecto correspondiente a esta sección,
hay que mencionar que éste último tiene dos tipos de administración: la administración
de Django (que se explicará a continuación) y la administración del servidor proxy.
Cabe destacar que ambas partes de administración tienen un acceso restringido, por
lo que para acceder a ellas es necesario identificarse con un usuario y contraseña
válidos.
Respecto a la funcionalidad de la administración de Django en este proyecto,
ésta se usa principalmente para administrar los usuarios que podrán acceder a la parte
de administración del servidor proxy. Por tanto, se podría decir que sirve para
administrar el acceso a la parte web del proyecto en sí, es decir, el portal web.
Para su creación, se ha usado la interfaz de administración de Django que
viene por defecto. Ésta constituye una de las partes más antiguas y potentes de
Django y se nutre de los metadatos de su modelo para proporcionar una interfaz
potente y lista para producción.
Para activar esta parte de Django hubo que realizar una serie de
modificaciones en diferentes archivos:
PROYECTO FIN DE CARRERA
69
En la opción INSTALLED_APPS del archivo settings.py de la raíz del
proyecto se añadió la línea "django.contrib.admin".
INSTALLED_APPS = (
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.sites',
'django.contrib.messages',
'django.contrib.admin',
Código 6-3: settings.py
En el archivo urls.py del directorio raíz del proyecto se añadió el patrón de
URL correspondiente a la sección del administrador de Django, de modo que para
acceder a ella habría que entrar en: http://127.0.0.1:8000/admin/ .
urlpatterns = patterns('',
#...
#admin
(r'^admin/', include(admin.site.urls)),
#...
)
Código 6-4: Fragmento de código de urls.py
Además de estos añadidos al código, se ha cambiado el aspecto del panel de
administración de Django para cambiar el estilo que trae por defecto. Para ello, se han
hecho modificaciones en las plantillas (alojadas en el directorio /templates)
correspondientes a esta sección.
6.1.1.4 Manager
El Manager es la parte desde donde se podrá administrar el proxy. Este panel
de administración está dividido en varias secciones, cada una de las cuales tiene un
cometido diferente. A continuación se describirán y explicarán dichas secciones.
6.1.1.4.1 RDF
Esta sección es utilizada para tratar los RDF. Para ello, internamente, se ha
hecho uso de la librería Redland (LibRDF)6. Gracias a ella, se han podido almacenar
en un endpoint los RDF que se carguen a través de dicha página, pudiendo hacer
incluso consultas a ellas mediante queries SPARQL. A la hora de almacenar un RDF
6 Ver punto 5.2.4.3 para más información sobre la librería Redland (LibRDF).
6. DESARROLLO
70
se debe elegir en qué base de datos se almacenará, ya que el servidor genera una
base de datos por página guardada en el proxy (es decir, cuando un usuario añade
una página al servidor proxy para posteriormente poder ser tratada, éste último crea
una base de datos propia para dicha página).
def manager_rdf_upload_page(request):
if request.method == 'POST':
form = UploadFileForm(request.POST, request.FILES)
# Check if the user has introduced an RDF file via the "url"
# field from the UploadFileForm class defined in 'forms.py'
if request.POST.get('url'):
if form.is_valid():
urlFile = request.POST.get('url')
filePath = settings.UPLOAD_URL
# Retrieve an RDF file from an url
download_rdf_file(urlFile,filePath)
rdfPath = urlFile
"""
# In order to complete the filePath we need to get
the
# name of the RDF file. To do that, first, we split
the
# URL
parts = []
for part in urlFile.split('/'):
parts.append(part)
# Afterwards, we add to the filePath the last part of
# the splitted url which is the name of the RDF file
filePath += parts[len(parts)-1]
"""
# If not, it means that the RDF file has been introduced via
# the "file" field
else:
if form.is_valid():
# Load an RDF file from the local machine
localFile = request.FILES['file']
handle_uploaded_file(localFile)
rdfPath = settings.UPLOAD_URL + localFile.name
# [FIXME] Store the RDF file in the DB (doesn't work
PROPERLY!)
dbName = form.cleaned_data['dataBases']
store_RDF(rdfPath, dbUser, dbPass, str(dbName))
return render_to_response('manager/thanks.html')
else:
form = UploadFileForm()
return render_to_response('manager/RDF.html', {'form': form},
context_instance=RequestContext(request))
Código 6-5: Fragmento de código de la función de manager/rdf
PROYECTO FIN DE CARRERA
71
La función que se muestra en el fragmento de código superior, corresponde al
bloque de código que maneja la llamada de “manager/rdf”. Esta función hace que
un RDF pueda ser subido al servidor proxy de dos formas: por un lado, descargándolo
desde un link introducido por el usuario, y por otro, subiéndolo desde un archivo local.
Para que estos cometidos puedan llevarse a cabo, se han creado otros
métodos como apoyo:
Para la descarga de un archivo de la URL indicada: download_rdf_file(url,
destination)
Este código está dentro de la carpeta /utils y es parte de la API7.
def download_file(url, destination):
"""Gets a file from an URL and stores in a destination
Keyword arguments:
url -- The url of the file to download
destination -- The path to store the downloaded file
"""
#get the file from Internet
tempFile = urllib2.urlopen(url)
parts = []
#split the URL(we want to get the last part(file name))
for part in url.split('/'):
parts.append(part)
#if the URL isn't pointing to a file, raise exception
if parts[len(parts)-1] == '' :
raise Exception, "The URL has to point to a concrete
file"
else:
#add to the destination the last part of the splitted
url (length -1)
destination += parts[len(parts)-1]
#open the destination file (with wb flags) and writes
the "buffer"
output = open(destination, 'wb')
output.write(tempFile.read())
#close the opened file
output.close()
Código 6-6: código del método de descarga dentro de utils
Para el guardado en el servidor de un archivo subido: handle_uploaded_file(f)
def handle_uploaded_file(f):
filePath = settings.UPLOAD_URL
7 Ver 6.2 para más información sobre la API.
6. DESARROLLO
72
filePath += f.name
destination = open(filePath, 'wb+')
for chunk in f.chunks():
destination.write(chunk)
destination.close()
Código 6-7: Código del método para tratar las subidas locales de RDF
Por último, una de las líneas más destacables de todo el código del método
“manage_rdf_upload” es la siguiente: store_RDF (rdfPath, dbUser, dbPass,
str(dbName)) .
Este método en concreto, hace que el RDF que se ha guardado (por defecto en
la carpeta static/uploads/) se inserte en la base de datos haciendo uso de la
librería Redland (LibRDF). Este método también es parte de la API:
def store_RDF(rdfPath, user, password, db):
"""Stores an RDF file (path or URL) in the Database
Keyword arguments:
rdfPath -- the RDF file path, could be a System path or a URL
user -- The user for accesing the DB
password -- The password of the user for accesing the DB
db -- The DB that we are going to access
"""
st= connect_librdf_mysql(user, password, db)
model=RDF.Model(st)
if not (rdfPath.startswith('http://') or
rdfPath.startswith('HTTP://')):
rdfPath = 'file:' + rdfPath
#Redland.librdf_model_transaction_start(model._model)
try:
# Do something
parser=RDF.Parser(name="rdfxml",mime_type="application/rdf+xml")
parser.parse_into_model(model, rdfPath)
#Redland.librdf_model_transaction_commit(model._model)
#model.sync()
except:
pass
#Redland.librdf_model_transaction_rollback(model._model)
print("["+ rdfPath +" RDF STORED ]")
#Redland.librdf_free_storage(st._storage);
Código 6-8: Código para el almacenaje de RDFs en la base de datos
6.1.1.4.2 Ontologías
El apartado de ontologías es bastante más simple, ya que a diferencia que con
los RDF, el servidor no descarga ontologías ni las almacena, sino que guarda una
PROYECTO FIN DE CARRERA
73
referencia a ellas (es decir, un nombre y una URL). Esto se debe a que las ontologías
son usadas mediante links establecidos dentro de los RDF y nunca aparecen
completos. Para la realización de esta sección se han usado los modelos de Django
para la base de datos en las ontologías. Para ello se ha creado un archivo models.py
que como se ha comentado previamente8, contendrá el modelo de la base de datos.
from django.db import models
# Create your models here.
class Ontology(models.Model):
name = models.CharField(max_length=30, unique=True)
url = models.CharField(max_length=200, unique=True)
def __unicode__(self):
return self.name
Código 6-9: Modelo de base de datos para las ontologías en Django
El método que obtiene los datos de la base de datos para visualizarlos o
insertarlos y que se los pasa a la plantilla se encuentra en manager/views.py y es
el siguiente:
def manager_ontologies_page(request):
insert = False
if request.method == 'POST':
form = InsertOntology(request.POST)
if form.is_valid():
#get data from the form
n = form.cleaned_data['name']
u = form.cleaned_data['url']
# create the model object
ont = Ontology(name=n, url=u)
try:
#save in the DB the new object, is in a try to
capture
#the exception if there is alredy an object
ont.save()
insert=True
except:
pass
#create a blank form again to return to the ontology
page
form = InsertOntology()
else:
form = InsertOntology()
#get all the objects from the ontology table
ontologies = []
8 Ver punto 5.2.2.3 (pag 26).
6. DESARROLLO
74
for e in Ontology.objects.all():
ontologies.append((e.name, e.url))
#the data for the html (variables...)
pageData = {'form': form,
'ontologies':ontologies,
'insert':insert,
}
#returning html, data, csrf token...
return render_to_response('manager/ontology.html', pageData,
context_instance=RequestContext(request))
Código 6-10: Método que interactúa con las ontologías de la BD
6.1.1.4.3 SPARQL queries
Muchos proyectos se centran en un modelo de base de datos propio en el cual
se basa toda la aplicación. Este proyecto, al estar basado en los metadatos, utiliza otro
tipo de almacenamiento y bases de datos y por consiguiente, las queries o consultas
también son bastante diferentes.
El método que se hace cargo de las queries o consultas a la base de datos
recibe en una variable, por un lado la propia query o consulta que se quiere realizar, y
por otro, la base de datos en la que se quiere hacer ésta. Esto último, se debe a que,
como se ha comentado previamente, existe una base de datos por página almacenada
en el proxy. Con la base de datos seleccionada y la query, la consulta puede ser
establecida. A continuación se muestra el método que se encarga de la petición de la
página:
def manager_sparql_queries_page(request):
if request.method == 'POST':
form = SparqlQuery(request.POST)
if form.is_valid():
#prepare the database and the query
db = form.cleaned_data['db']
query = form.cleaned_data['query']
output = form.cleaned_data['output']
#execute the query
#qres = sparql_query(query, dbUser, dbPass, db, output)
qres = sparql_query(query, dbUser, dbPass, str(db))
#pretiffy the XML with indentation
xmlQres = xml.dom.minidom.parseString(qres)
resultList = xmlQres.toprettyxml()
#transform the query result to a list if is python
"""if(output == "xml"):
#pretiffy the XML with indentation
xmlQres = xml.dom.minidom.parseString(qres)
resultList = xmlQres.toprettyxml()
else:
resultList = qres
"""
#response with the html page and the results
PROYECTO FIN DE CARRERA
75
return render_to_response('manager/sparqlresult.html',
{'resultList': resultList,
'output':output},context_instance=RequestContext(request))
else:
form = SparqlQuery()
pageData = {'form': form,
}
#returning html, data, csrf token...
return render_to_response('manager/sparql.html', pageData,
context_instance=RequestContext(request))
Código 6-11: Método encargado de la página de queries
El resultado de la consulta puede ser de varios tipos aunque actualmente sólo
está habilitado el resultado en RDF/XML, puesto que es el más usado. El método
encargado de ejecutar la query sobre la base de datos es parte de la API:
def sparql_query(query, user, password, db, output=None):
""" Makes a sparql query to the SQLite database and returns a
result
Keyword arguments:
query -- the query to execute
user -- The user for accesing the DB
password -- The password of the user for accesing the DB
db -- The DB that we are going to access
output -- the output type could be xml only, for now, so The is
no parameter
Returns a result (rdflib result)
"""
st= connect_librdf_mysql(user, password, db)
model=RDF.Model(st)
q1 = RDF.Query(query ,query_language='sparql')
q1Result = q1.execute(model)
#q1Result = model.execute(q1)
print("[ SPARQL QUERY DONE ]")
#Redland.librdf_free_storage(st._storage);
#return in str(XML)
return q1Result.to_string()
Código 6-12: Método encargado de la ejecución de queries SPARQL
Tras haber realizado la consulta, en el método previo a este (el de views.py)
hace que se redirija a una página donde aparecerá el resultado de la consulta,
pasándole el filtro de Pygments9 haciendo que de esta forma salga con resaltado de
sintaxis. Esto facilita la lectura del bloque de código RDF/XML obtenido de la consulta
SPARQL.
9 Ver punto 5.3.2 para más información sobre Pygments.
6. DESARROLLO
76
6.1.1.4.4 Webs
Uno de los principales aspectos de este proyecto es su utilidad como proxy.
Para que esto sea posible, es necesario que se le añadan con anterioridad las webs a
las que podrá redirigir cuando un cliente se lo pida al servidor. Por ello, es necesario
un apartado desde donde poder administrar las webs. A través de este administrador
se pueden añadir y eliminar las webs que se deseen, actualizándose automáticamente
la lista de Webs de la página de inicio, donde se podrá acceder a los proxies de las
páginas añadidas.
En el archivo views.py del directorio /manager están los métodos a los que
les corresponde la tarea de añadir y eliminar las webs.
def manager_addweb_page(request):
insert = False
if request.method == 'POST':
form = addWebForm(request.POST)
if form.is_valid():
#get data from the form
n = form.cleaned_data['name']
u = form.cleaned_data['url']
#add url to the settings set the flag to good insertion,
insert_delete_web_in_settings(u, n, True)
insert=True
#create dir
newFolderPath = 'scripts/'+n+'/'
fileName = 'ModifyBody.py'
#prepare dir (init and default script)
create_dir(newFolderPath)
create_blank_file(newFolderPath+'__init__.py')
shutil.copyfile('scripts/' + fileName, newFolderPath +
fileName)
#create a blank form again
form = addWebForm()
else:
form = addWebForm()
#the data for the html (variables...)
pageData = {'form': form,
'webs':settings.REVPROXY_SETTINGS,
'insert':insert,
}
#returning html, data, csrf token...
return render_to_response('manager/addweb.html', pageData,
context_instance=RequestContext(request))
Código 6-13: Método para añadir una web proxy
PROYECTO FIN DE CARRERA
77
Como se puede apreciar en el código anterior, este método hace una serie de
pasos (llamando a otros métodos secundarios):
1. Añade la nueva web insertada a la tupla que contiene las webs en
settings.py10.
2. Crea un directorio dentro de la carpeta /scripts con el nombre identificativo
que se le ha dado la URL.
3. Crea un fichero __init__.py dentro de ese directorio recién creado.
4. Copia el script por defecto al nuevo directorio.
En cuanto a la eliminación de páginas web, el método correspondiente es el
siguiente:
def manager_addweb_delete_page(request, id):
n = id
#search for the element in the list
for item in settings.REVPROXY_SETTINGS:
if item[0] == n:
u = item[1]
#delete from settings
insert_delete_web_in_settings(u, n, False)
#delete dir
rmFolderPath = 'scripts/'+n+'/'
delete_dir(rmFolderPath)
break
return HttpResponseRedirect("/manager/addweb")
Código 6-14: Método para la eliminación de páginas web proxy
Para la eliminación de una página web el proceso es algo más simple:
1. Se elimina la página web de la tupla de webs proxy en settings.py.
2. Se elimina todo el directorio con el nombre del identificativo de la página web a
eliminar. Se eliminarían todos los scripts que hubiese dentro y el fichero
__init__.py.
6.1.1.4.5 Scripts
Los scripts son una parte fundamental del servidor proxy, ya que en ellos reside
la lógica y el comportamiento de lo que debe hacer éste antes de entregar el resultado
obtenido del servidor de la web original sin alterar. Para ello se necesita un cargador
de scripts, que hará algo parecido al cargador de webs11. El código de
manager/views.py es el siguiente:
10
Ver punto 5.2.3.3 para más información. 11
Ver punto 6.1.1.4.4 para más información sobre el cargador de webs.
6. DESARROLLO
78
def manager_scripts_page(request):
if request.method == 'POST':
form = UploadScriptForm(request.POST, request.FILES)
if form.is_valid():
localFile = request.FILES['file']
db = form.cleaned_data['dataBases']
handle_uploaded_script(localFile, db)
return render_to_response('manager/thanks.html')
else:
form = UploadScriptForm()
return render_to_response('manager/scripts.html', {'form': form,
'scriptUrls': settings.REVPROXY_SETTINGS},
context_instance=RequestContext(request))
Código 6-15: Método para la subida de scripts al servidor
El código anterior, hace algo similar a lo que se hacía con los RDFs: se sube
un archivo al servidor guardándolo en local. De esta forma, todos los scripts serán
guardados en el directorio que les corresponde, ya que al subirlos habrá que elegir a
cuál de las páginas pertenece, reemplazando así el script por defecto siempre que se
llame de la misma forma (es decir, ModifyBody.py).
Asimismo, esta sección también permite ver el script que hay actualmente
activo en la página. Para ello existe otro método que hará que el script pase por los
filtros de Pygments, resaltando así la sintaxis al igual que pasaba con los resultados
de las consultas SPARQL. Dicho método es el siguiente:
def manager_scripts_code_page(request, id):
try:
#get the script in a string
strScript = read_file_Script(id)
#insert the script in the variable of datas
pageData = {'id': id,
'strScript': strScript,
}
return render_to_response('manager/scriptsCode.html',
pageData)
except:
return HttpResponseRedirect("/manager/scripts")
Código 6-16: Método para la visualización de los scripts
6.1.1.5 Login
Una vez explicados los dos paneles de administración, se puede proceder a
explicar el método de login/logout el servidor proxy. Hay que mencionar que a pesar
de que a simple vista parezca que existan dos logins diferentes (uno para cada uno de
los paneles de administración mencionas en los puntos anteriores), en realidad, una
vez que un usuario se ha autentificado correctamente a través de alguno de ellos, éste
PROYECTO FIN DE CARRERA
79
no necesitará volver a hacerlo para acceder al otro panel de administración. Es decir,
una vez ingresado en la página, el usuario continuará estando logeado hasta que
él/ella indique que quiere hacer el logout.
Para la parte del login del Manager se han tenido que hacer unas pequeñas
modificaciones en el código:
urlpatterns = patterns('',
#...
#login/logout
(r'^login/$', 'django.contrib.auth.views.login'),
(r'^logout/$', logout_page),
#...
#manager
(r'^manager/', include(manager.urls)),
Código 6-17: Fragmento de código de urls.py
En urls.py se ha añadido el código necesario para indicar a dónde tiene que
redirigir Django cuando se necesite acceder al login. En este caso, se llama a un
método propio de Django ('django.contrib.auth.views.login') para que
tramite el login.
Por otro lado, también se ha añadido una indicación para saber a dónde debe
redirigir cuando se acceda al Manager (panel de administración del proxy). En este
caso incluye las URLs que están descritas en el archivo manager/urls.py. Como se
puede presuponer, la página de login aparece cuando se intenta acceder al
administrador del proxy (cuando se accede a http://xxxxxxxx.xxx/manager) y no se
está autentificado.
urlpatterns = patterns('',
#...
# Main web entrance.
(r'^$', manager_main_page),
#...
)
Código 6-18: Fragmento de código de /manager/urls.py
En el bloque de código anterior se puede observar como cuando al acceder al
Manager, el usurario será redirigido al método “manager_main_page()”.
@login_required
def manager_main_page(request):
"""
If users are authenticated, direct them to the main page. Otherwise,
6. DESARROLLO
80
take them to the login page.
"""
return render_to_response('manager/index.html')
Código 6-19: manager/views.py
Este último método, que es al que se redirige cuando se intenta acceder a la
página principal del Manager del proxy, se encuentra en views.py dentro de la
carpeta /manager. Como se explicó anteriormente, en views.py se almacenan los
métodos a los que se llamará cuando se acceda a una página (URL) en particular.
La magia de Django viene por el filtro que se le aplica al método. Con sólo
poner encima del método “@login_required”, automáticamente Django sabe que
es obligatorio haber hecho login antes de poder redirigir a la página.
En registration/login.html tenemos la plantilla que el usuario verá
cuando sea redirigido a la página de login:
{% extends "base.html" %}
{% block head %}
<title>Meta Proxy | Login</title>
{% endblock %}
{% block body %}
<section>
<div id="content-wrap">
<div id="loginBox">
<h2>Login</h2>
{% if form.errors %}
<p>Your username and password didn't match, please try
again.</p>
{% endif %}
<form method="post" action=".">{%csrf_token%}
<div id="login">
<img src="/static/img/lock.png" alt="Login" id="imgLogin"/>
<div id="loginForm">
<p>
<label for="id_username">Username:</label>
{{ form.username }}
</p>
<p>
<label for="id_password">Password:</label>
{{ form.password }}
</p>
{% if next %}
<input type="hidden" name="next" value="{{ next }}" />
{% else %}
<input type="hidden" name="next" value="/manager/" />
{% endif %}
<p>
PROYECTO FIN DE CARRERA
81
<input type="submit" value="login"
id="submitButton"/>
</p>
</div>
</div>
</form>
</div>
<div id="line"></div>
<div class="clearfix"></div>
</div>
</section>
{% endblock %}
Código 6-20: templates/registration/login.html
6.1.2 Proxy
Como se ha citado anteriormente, la funcionalidad principal del proyecto está
en el proxy y en la lógica que se encarga de cambiar el comportamiento de una página
web. Para ello ha habido que modificar el comportamiento de la aplicación dj-
Revproxy12, el cual ha sido posible tras realizar un estudio minucioso de su código. Por
defecto, la aplicación dj-Revproxy funciona de una forma simple: al recibir una petición
de una página web, la intenta satisfacer reenviando al cliente el HTML de la fuente
original intacta.
Sin embargo, este proyecto quería ir un paso más allá y hacer que ese
comportamiento intermedio, antes de enviar el HTML al cliente, pudiera ser modificado
como uno quisiese, dándole el comportamiento más adecuado a los requisitos que
quisiésemos satisfacer. Pese a que el proyecto ha sido orientado a la Web Semántica,
eso no quita que esta herramienta se haya creado pensando en la flexibilidad,
pudiendo darle así usos alternativos13 a ésta.
Para entender como se ha conseguido cambiar el comportamiento del proxy.
Hay que profundizar un poco en el formato de un paquete HTTP y en la forma que se
ha diseñado la API. Por ello, a continuación se describirá el código poco a poco.
#if the type of the "package" isn't text and html, we don't want to
# edit the bytes, because we will destroy the images, css...
i = find_in_list(headers, 'Content-Type')
if headers[i][1] == 'text/html':
#get path and split in "/" parts
actualPath = request.get_full_path()
parts = []
for part in actualPath.split('/'):
parts.append(part)
#create the import string. Ex: scripts.dipina.ModifyBody
importString = "scripts."
12
Ver punto 5.2.3 para más información sobre dj-Revproxy. 13
Ver punto 7 para más información sobre usos alternativos.
6. DESARROLLO
82
importString += parts[2] #The 3rd position is where the id
is
importString += ".ModifyBody"
#import in a local var
mBImport = __import__(importString, fromlist=['*'])
"""
if "dipina" in actualPath:
from scripts.dipina.ModifyBody import *
print "importado!!!!!"
elif "dbujan" in actualPath:
from scripts.dbujan.ModifyBody import *
#...
"""
#read tee object (tee to string)
tmpBody = body.read()
#if isn't implemented return normal page
try: #uncomment try for development
#create instance of implementation class of
ModifyBodyBase
mb = mBImport.ModifyBody(tmpBody, headers, proxied_url)
mb.body_modification_logic()
body = mb.body
#Obtain the index of the content. Now we know where to
change
i = find_in_list(headers, 'Content-Length')
#Calculate the length (needs >= Python 2.6)
length = sys.getsizeof(body)
#An empty string type variable in python is 40, so we
rest to obtain the content length
length = length - 40
#Is a tuple, so is inmatuable, so we have to create a
new one
tupla = ('Content-Length', length)
headers[i] = tupla
except:
body = tmpBody
El código de la parte superior está ubicado en revproxy/proxy.py y
pertenece al método def proxy_request(request, destination=None, prefix=None,
headers=None,no_redirect=False, decompress=False, rewrite_base=False, **kwargs) .
Para comenzar con la explicación, habría que describir qué tipos de datos
tenemos para trabajar:
headers: que será la variable que contendrá en una lista la cabecera de cada
paquete HTTP. Esta lista estará formada por tuplas de (clave, valor).
body: que será la variable que contiene todo el HTML, imágenes, etc. de la
página solicitada (N.A: Habrá más de un paquete por petición).
PROYECTO FIN DE CARRERA
83
Para entender mejor el código, primero habría que explicar el paquete HTTP
haciendo hincapié en la cabecera. Dentro de la cabecera existen muchos argumentos,
sin embargo, los relevantes para la explicación de este proyecto unos pocos.
La siguiente imagen describe perfectamente la estructura de un paquete HTTP:
Por otro lado, en ésta otra, se describen los campos que contienen una
cabecera de un paquete HTTP:
Ilustración 6-2: Estructura de un paquete HTTP
Ilustración 6-3: Algunos argumentos de la cabecera de un paquete HTTP
6. DESARROLLO
84
Como se puede apreciar, algunos de los argumentos más importantes son los
siguientes:
Date
Content location
Content length
Content type
Volviendo al código previamente expuesto, empezaremos por las variables
headers y body. Lo primero que se hace es obtener el tipo de dato con el que estamos
trabajando, ya que la respuesta del servidor se hace en varias partes (HTML, Imagen,
etc.). Por tanto, hay que saber de qué tipo es ya que el script sólo interactúa con
HTML y en caso de modificar una imagen haría que ese paquete http correspondiente
a la imagen quedara corrupto. Tras analizar el contenido del paquete (usando el
argumento 'Content-Type’) y verificar que es de tipo 'text/html', se pasa a la obtención
del método implementado (es decir, el script introducido) que modificará el HTML para
después devolvérselo al cliente. Asimismo, puesto que el proyecto puede ejercer de
proxy de varias páginas al mismo tiempo, es necesario saber cuál es el script que se
debe ejecutar.
Después de esto, se obtendrá el HTML del paquete HTTP y se creará un objeto
con la API diseñada14, se ejecutará el método de la clase implementada en el script,
teniendo ya el HTML del paquete HTTP modificado. Por último, faltaría un detalle
importante por comentar y es que el tamaño del paquete HTTP sigue con el tamaño
original (antes del cambio realizado mediante el script) pese a que se han realizado
cambios en el código HTML. Por tanto, es necesario calcular el nuevo tamaño (para la
cual se requiere una versión de Python mayor o igual a la 2.6) para poder seguir con el
flujo de ejecución y poder devolver el paquete al cliente posteriormente. Si no se
realizara este pequeño detalle, el cliente no vería páginas completas o las vería mal
formadas.
Es importante destacar que la modificación tanto de las cabeceras como del
cuerpo del paquete HTTP está implementada con excepciones de forma que si algo
fallará se devolvería el paquete original y funcionaría como un proxy normal.
Obviamente, este detalle es importante desactivarlo a la hora de desarrollar y probar
scripts para saber dónde se encuentran los errores.
6.1.3 Scripts
Los scripts son los “programas” o instrucciones que harán que el proxy actúe
de una forma u otra. Esto significa que dependiendo del script, el proxy modificará la
página solicitada de una manera u otra. Para entender los scripts que se van a explicar
a continuación, es importante primero ver la API de este proyecto.
14
Ver punto 6.2 para más información acerca de la API.
PROYECTO FIN DE CARRERA
85
Cabe destacar que todos los scripts tienen un comportamiento similar. Más
adelante, en la sección de la API (punto 6.2), se explicarán más extensamente. Sin
embargo, como explicación breve de su funcionamiento, se puede decir que: primero
se obtiene el HTML original del atributo de la clase que se reimplementa, a
continuación se hacen una serie de cambios u operaciones y por último, se vuelve a
asignar al atributo.
Actualmente, el proyecto tiene un script por defecto que lo que hace es extraer
datos semánticos de páginas web. No obstante, también hay otros scripts que han
sido sobrescritos sobre el script original cuyo cometido es diferente al que persigue
este proyecto. Esto se ha hecho para demostrar el potencial de la herramienta y para
destacar que no está sujeto sólo a la web semántica, aunque su desarrollo se haya
hecho pensando principalmente en esto.
Básicamente, en el servidor proxy existen tres scripts diferentes aplicados a
cuatro páginas diferentes registradas en él, las cuales se utilizarán como prueba de
concepto. Las funciones que realizan estos tres scripts son las siguientes:
Cambiar el aspecto de una página.
Añadir un cliente de Twitter a una página.
Extracción de los metadatos de una web mediante la búsqueda de archivos
RDF y también mediante técnica GRDDL (éste es el script por defecto que se
aplicará a todas la páginas registradas en el servidor proxy si no se asocia a
ellas otro script con cometido diferente).
6.1.3.1 Cambio de aspecto
Este script en concreto está hecho para la página del profesor David Buján,
puesto que usa su CSS como base (no sería del todo estable usarlo para otra página
diferente, debido a que probablemente, usaría otro CSS diferente). Salvo esta
pequeña obviedad, el script, previa realización de un pequeño cambio, valdría para
cambiar el aspecto de otras páginas.
import abc
import urllib2
import re
from utils.utils import debug_print
from utils.rdf import rdf_to_graph_file
from scripts.ModifyBodyBase import ModifyBodyBase
from django.conf import settings
class ModifyBody(ModifyBodyBase):
def __init__(self, body, headers, proxied_url):
self.body = body
self.headers = headers
self.proxied_url = proxied_url
6. DESARROLLO
86
@property
def proxied_url(self):
return self._proxied_url
@proxied_url.setter
def proxied_url(self, newProxied_url):
self._proxied_url = newProxied_url
@property
def body(self):
return self._body
@body.setter
def body(self, newBody):
self._body = newBody
@property
def headers(self):
return self._headers
@headers.setter
def headers(self, newHeaders):
self._headers = newHeaders
def body_modification_logic(self):
debug_print(self.headers)
#we will work with utf8
self.body = unicode(self.body, "utf-8", errors='replace')
newBody = self._change_Css()
headHtml = self._get_Head_and_insert_Css(newBody)
bodyHtml = self._get_body_html(newBody)
self.body = headHtml + bodyHtml
def _change_Css(self):
body = self.body
newCss = "/static/css/bujan.css"
regularExpressionIn = '\w+\.css'
reg = re.compile(regularExpressionIn)
m = reg.search(body)
changedHtml = body[:m.start(0)] + newCss + body[m.end(0):]
return changedHtml
def _get_Head_and_insert_Css(self, body):
print "####[getting head]####"
posHead = body.find("</head>") - 1
webCss= '<link href="/static/css/proxiedWeb.css"
rel="stylesheet" type="text/css" />'
PROYECTO FIN DE CARRERA
87
bodyAux = body[:posHead] + webCss + body[posHead:]
head = bodyAux[: bodyAux.find("</head>") + 7]
#convert result to unicode(if they are unicode already
exception will be catch and wouldn't be done nothing)
try:
head = unicode(head, "utf-8", errors='replace')
except:
pass
return head
def _get_body_html(self, body):
regularExpressionIn = '<body[\w"= ]*>'
reg = re.compile(regularExpressionIn)
m = reg.search(body)
homeButton = '\n<div id="homeLink"><a href="/"><img
id="homeButton" src="/static/img/home.png" alt="Return
Home"/></a></div>'
bodyTagSize = m.group(0)
finalHtml = body[m.start(0):m.end(0)] + homeButton +
body[m.end(0):]
return finalHtml
Código 6-21: ModifyBody.py de la página dbujan
Como se ve en el código, para poder realizar la acción de búsqueda de ciertas
secciones del código HTML se hace uso de las expresiones regulares, algo en lo que
Python es extremadamente potente y común. Una vez localizados las secciones del
código HTML que interesan, se hacen los cambios pertinentes (como en este caso, el
cambio del archivo CSS original, por el nuevo) y por último se asigna de nuevo el
objeto, creando así la página proxy modificada.
También es destacable comentar que se inserta un botón de “home” en la parte
superior de la página proxy para poder regresar a la página inicial del servidor proxy.
6.1.3.2 Integración de cliente Twitter
Twitter es una red social basada en el microblogging. Esta red permite mandar
mensajes de texto plano de un máximo de 140 caracteres, llamados tweets, que se
muestran en la página principal del usuario. Es más, los usuarios pueden suscribirse a
los tweets de otros usuarios mostrándolos en su página principal si así se desea. Por
defecto, los mensajes son públicos, pudiendo difundirse privadamente mostrándolos
únicamente a seguidores. Los usuarios pueden twittear desde la web del servicio o
desde aplicaciones oficiales externas.
6. DESARROLLO
88
Con este segundo script se consigue integrar un cliente de Twitter en la página
que el cliente ha solicitado y a su vez, hacer que cada cierto tiempo cargue los tweets
de la gente que el script diga. Para ello, se hace uso de tecnología JavaScript y un
plug-in de software libre llamado “Tweet!”.
import abc
import urllib2
import re
import RDF
from scripts.ModifyBodyBase import ModifyBodyBase
from django.conf import settings
import BeautifulSoup
class ModifyBody(ModifyBodyBase):
def __init__(self, body, headers, proxied_url):
self.body = body
self.headers = headers
self.proxied_url = proxied_url
@property
def proxied_url(self):
return self._proxied_url
@proxied_url.setter
def proxied_url(self, newProxied_url):
self._proxied_url = newProxied_url
@property
def body(self):
return self._body
@body.setter
def body(self, newBody):
self._body = newBody
@property
def headers(self):
return self._headers
@headers.setter
def headers(self, newHeaders):
self._headers = newHeaders
def body_modification_logic(self):
#we will work with utf8
self.body = unicode(self.body, "utf-8", errors='replace')
#HTML Head block modification
self._modify_HTML_head()
#HTML Body block modification
self._modify_HTML_body()
PROYECTO FIN DE CARRERA
89
def _modify_HTML_head(self):
initializeTweet = """
<script language="javascript"
src="http://ajax.googleapis.com/ajax
/libs/jquery/1.6.2/jquery.min.js"
type="text/javascript">
</script>
<script language="javascript"
src="http://tweet.seaofclouds.com/jq
uery.tweet.js"
type="text/javascript">
</script>
"""
tweetJsFunc = """
<script type='text/javascript'>
$(document).ready(function(){
$(".tweet").tweet({
username: ["sharem",
"slok69"],
avatar_size: 32,
count: 5,
loading_text: "loading
tweets..."
});
});
</script>
"""
tweetCss = '<link
href="http://tweet.seaofclouds.com/jquery.tweet.css" media="all"
rel="stylesheet" type="text/css"/> '
homeCss = '<link href="/static/css/proxiedWeb.css"
rel="stylesheet" type="text/css" />'
#Search and create the new head
pattHeadFinish = '</head>'
regexHeadFinish = re.search(pattHeadFinish, self.body)
bodyAux = self.body[:regexHeadFinish.start(0)] +
initializeTweet + tweetJsFunc + tweetCss + homeCss +
self.body[regexHeadFinish.start(0):]
self.body = bodyAux
def _modify_HTML_body(self):
homeButton = '<div id="homeLink"><a href="/"><img
id="homeButton" src="/static/img/home.png" alt="Return
Home"/></a></div>'
#tweetPlace = '<div class="tweet"></div> '
tweetPlace = '<center> <div class="tweet"
style="width:400px; text-align:left"></div> </center>'
#place the home button
pattBodyStart = '<body[\w"= ]*>'
regexBodyStart = re.search(pattBodyStart, self.body)
self.body = self.body[:regexBodyStart.end(0)+1] +
homeButton + self.body[regexBodyStart.end(0)+1:]
6. DESARROLLO
90
#place the twitter plugin at the bottom
pattBodyFinish = '</body>'
regexBodyFinish = re.search(pattBodyFinish, self.body)
bodyAux = self.body[:regexBodyFinish.start(0)] + tweetPlace
+ self.body[regexBodyFinish.start(0):]
self.body = bodyAux
Código 6-22: ModifyBody.py de la página slok
La funcionalidad de este script es similar a la del script de cambio de aspecto,
salvo por que en éste hay que configurar más cosas como el programa o JavaScript
de Twitter que se va a aplicar. Por decirlo de forma simple, se intenta inyectar código
JavaScript dentro del bloque de HTML tanto en el bloque <head> como en el bloque
<body> de dicha página.
6.1.3.3 Extractor de metadatos (RDF y GRDDL)
Este script es el script por defecto que aplica el servidor proxy a toda aquella
página que haya sido añadida en él. Su cometido es hacer de extractor de metadatos
y los formatos de metadatos que soporta son RDF y GRDDL15. En cuanto al RDF, para
extraerlo debe detectar un archivo local que sea de tipo RDF (xxxx.rdf). En cuanto a
GRDDL, detectará si existen en el HTML las instrucciones necesarias para saber si
existe GRDDL. En esta ocasión, el código fuente de este script se analizará por
bloques, ya que este código es bastante más extenso que los anteriores scripts y se
hacen llamadas a métodos externos de la API que son importantes de destacar.
Una explicación sencilla del script sería que éste coge la página y la modifica
de forma que incluye una serie de pestañas en la parte superior de ésta. En una de
estas pestañas aparece la página original sin modificar. Seguidamente, el script creará
otras X pestañas (pestañas de metadatos), una por cada archivo RDF que encuentre
en el código HTML de la página original. Por último, también existirá una pestaña para
el GRDDL.
En cada pestaña de metadatos se extraerá el XML del RDF y se mostrará en
forma de código resaltando su sintaxis para facilitar la lectura. Además debajo de este
código XML aparecerá el RDF en forma de grafo en formato SVG. Para ello existe un
visor mediante el cual se podrá mover el grafo e incluso hacer zoom en él con un
máximo de aumento de 800%.
import abc
import urllib2
15
Ver 3.7 para más información sobre GRDDL.
PROYECTO FIN DE CARRERA
91
import re
import RDF
from utils import rdf
from scripts.ModifyBodyBase import ModifyBodyBase
from django.conf import settings
import BeautifulSoup
class ModifyBody(ModifyBodyBase):
def __init__(self, body, headers, proxied_url):
self.body = body
self.headers = headers
self.proxied_url = proxied_url
@property
def proxied_url(self):
return self._proxied_url
@proxied_url.setter
def proxied_url(self, newProxied_url):
self._proxied_url = newProxied_url
@property
def body(self):
return self._body
@body.setter
def body(self, newBody):
self._body = newBody
@property
def headers(self):
return self._headers
@headers.setter
def headers(self, newHeaders):
self._headers = newHeaders
Código 6-23: Comienzo del fichero ModifyBody.py por defecto
El código de la parte superior corresponde al comienzo del script mencionado.
Primero Hace los import pertinentes para poder usar ciertos métodos de clases ya
creadas por Python, de librerías de terceros y de la API creada para este proyecto.
Después, se hereda de la clase abstracta necesaria para que funcione el script y se
implementan los getter y setter.
El método que se muestra a continuación es un método obligatorio de
implementar, ya que es el que debe tener la lógica que se le aplica al HTML. En este
caso lo primero que se hace es cambiar todo el HTML al formato de codificación de
caracteres UTF8. En caso de existir errores por cambio de codificación, en vez de
lanzar una excepción Python intenta reemplazarlos. Seguidamente, se llaman a los
respectivos métodos donde se modificarán la cabecera del HTML (<head> </head>) y
el cuerpo (<body> </body>).
6. DESARROLLO
92
def body_modification_logic(self):
#we will work with utf8
self.body = unicode(self.body, "utf-8", errors='replace')
#HTML Head block modification
self._modify_HTML_head()
#HTML Body block modification
self._modify_HTML_body()
Código 6-24: Método de la lógica en ModifyBody.py por defecto
def _modify_HTML_head(self):
"""
Gets the head html block of the HTML and applys all the
needed modifications
for example add css, javascripts... then saves in the
attribute body
"""
#Code that we will insert in the head
jQScript = """
<link
href="http://ajax.googleapis.com/ajax/libs/jqueryui/1.8/themes/base/
jquery-ui.css" rel="stylesheet" type="text/css"/>
<script
src="http://ajax.googleapis.com/ajax/libs/jquery/1.4/jquery.min.js">
</script>
<script
src="http://ajax.googleapis.com/ajax/libs/jqueryui/1.8/jquery-
ui.min.js"></script>
<link href="/static/css/proxiedWeb.css"
rel="stylesheet" type="text/css" />
<script>
$(document).ready(function() {
$("#tabs").tabs();
$("#viewer").iviewer({
update_on_resize: true,
initCallback: function ()
{
var object = this;
object.fit();
$("#in").click(function(){
object.zoom_by(1);});
$("#out").click(function(){
object.zoom_by(-1);});
$("#fit").click(function(){
object.fit();});
$("#orig").click(function(){
object.set_zoom(100); });
$("#update").click(function(){
object.update_container_info();});
},
PROYECTO FIN DE CARRERA
93
onMouseMove: function(object, coords)
{ },
onStartDrag: function(object, coords)
{ },
onDrag: function(object, coords) { }
});
});
</script>
<link href="/static/css/shCore.css"
rel="stylesheet" type="text/css" />
<link href="/static/css/shThemeRDark.css"
rel="stylesheet" type="text/css" />
<script type="text/javascript"
src="/static/js/shCore.js"></script>
<script type="text/javascript"
src="/static/js/shBrushXml.js"></script>
<script type="text/javascript"
src="/static/js/jquery.iviewer.js"></script>
<script type="text/javascript"
src="/static/js/jquery.mousewheel.min.js"></script>
<link href="/static/css/jquery.iviewer.css"
rel="stylesheet" type="text/css" />
"""
#regular expressions for searching the head block, insert
data and then save in the class attribute
#pattHeadStart = '<head[\w"=\/\:\.\- ]*>'
pattHeadFinish = '</head>'
#regexHeadStart = re.search(pattHeadStart, body)
regexHeadFinish = re.search(pattHeadFinish, self.body)
bodyAux = self.body[:regexHeadFinish.start(0)] + jQScript +
self.body[regexHeadFinish.start(0):]
self.body = bodyAux
#convert result to unicode(if they are unicode already
exception will be catch and wouldn't be done nothing)
"""try:
head = unicode(head, "utf-8", errors='replace')
except:
pass
"""
Código 6-25: Método para modificación de la cabecera del HTML que está en ModifyBody.py
Este método es el que modifica la cabecera del HTML para insertarle todo lo
que se desee, como puede ser jQuery para la creación de las pestañas en la parte
superior de la página, el plug-in en JavaScript para el resaltado de sintaxis y el visor de
imágenes SVG con el que podremos navegar por el grafo. Para poder insertar todo
este nuevo código HTML dentro del HTML original, se han hecho uso de las
6. DESARROLLO
94
expresiones regulares16, ya que son rápidas para la búsqueda de patrones y son
bastante flexibles una vez que se da con el patrón adecuado.
El próximo método que se va a explicar es el que modifica el cuerpo de HTML.
Para ello hace uso de varios métodos, por tanto, primero, antes de mostrar su código,
se explicarán los métodos que usa.
def _createTabs(self):
"""
This method 'creates' alll the tabs, technically, this
method does all the calls
for all the neccesary tabs(RDF/GRDDL), then returns a
tuple with two vars, the
first position of the tuple are the declarations of the
tabs, and the second position
are the contents of all the declared tabs. They are
separate because the jquery plugin
need first to declare, and then when all the tabs are
declared, put the content
"""
#tab necessary data
mainTab = '\n<li><a href="#fragment-
web"><span>WebPage</span></a></li>'
tabs = mainTab
tabContent=''
cont = 0
links = self._getAllRdfLinks()
#Declare XML/RDF TABS and create content
for i in links:
#split the url to get the final name
tmp = i.split('/')
name = tmp[len(tmp)-1] #get the last array postion (the
name of the file, ex: foaf.rdf)
name = name.split('.')
finalName = name[0] #get the las array position (the
name of file without extension, ex: foaf)
finalNamePar = finalName + '(RDF/XML)'
#create the HTML code for the tab declaration
tabs = tabs + '\n<li><a href=\"#fragment-'+ finalName
+'\"><span>' + finalNamePar + '</span></a></li>'
#create RDF tab
downloadedXml = urllib2.urlopen(i).read() #get RDF
content
try:
#if we want to print there is the need to change
errors to 'ignore'
downloadedXml = unicode(downloadedXml, "utf-8",
errors='replace')
except:
pass
#and create the whole content tab
16
Ver punto 3.6 para más información sobre expresiones regulares.
PROYECTO FIN DE CARRERA
95
tabContent +=
self._createSingleXMLGraphTab(downloadedXml, finalName, i, cont)
cont += 1
#Declare GRDDL TAB and create content (if there is in the
html...)
if self._checkGRDDL():
tabs = tabs + '\n<li><a href=\"#fragment-
grddl\"><span>GRDDL Parsing</span></a></li>'
tabContent +=
self._createSingleXMLGraphTab(self._parseGRDDL(),'grddl', None,
cont)
cont +=1
#return a tuple with: (tab declarations, tab contents)
return (tabs, tabContent)
Código 6-26: Método para creación de todas las pestañas en ModifyBody.py
Este método es el que hace que se genere todo el HTML necesario de todas
las pestañas de la parte superior de la página proxy. En realidad este método hace
llamadas a un método que crea una pestaña única. Este último, será llamado tantas
veces como ficheros RDF que encuentre, así como para generar la pestaña
correspondiente al GRDDL.
def _createSingleXMLGraphTab(self, contentStr, key, url, cont):
"""
Creates a single tab that is XML and Graph type, like
the RDFs or the GRDDLs,
this tabs consist in an XML String and graph
representation of that XML.
receives: the content of the tab(the XML string), and
the key(is the title of the tab),
the url of the XML file, and the counter of the tab(this
is for the iviewer)
"""
preStart = """
<div id = "code">
<div id="codeBox">
<pre class="brush: xhtml">\n
"""
preEnd = """
\n</pre>
</div>
</div>
<script>
$(document).ready(function() {
var iviewer = {};
$("#graphViewer"""+str(cont+1)+"""\").iviewer(
{
"""
end= """
6. DESARROLLO
96
initCallback: function()
{
iviewer = this;
}
});
});
</script>
<div class="wrapper">
<div id="graphViewer"""+str(cont+1)+"""\"
class="viewer" ></div>
<br />
</div>
</div>
"""
#add the tab block head(ex: <div id="fragment-grddl">)
tmp = '<div id=\"fragment-'+ key +'\">'
#GRAPH TIME!!
#create the destination for saving the SVG graph
graphDest = 'static/tmp/'+str(key)+'.svg'
#In GRDDL we have the exception that the graph is made with
an string and not with an URL
if url == None:
rdf.str_to_graph_file(contentStr, self.proxied_url,
graphDest, 'svg') #the url is this (actual url)
else:
rdf.rdf_to_graph_file(url, graphDest, 'svg')
#We retrieve the dir of the src image to show it in the
viewer
imgSource=' src: "/'+graphDest+'",'
#assemble the final tab code, now we have a awesome complete
tab. ta-da!! :D
code = tmp + preStart + contentStr + preEnd + imgSource +
end
return code
Código 6-27: Creación de una única pestaña en ModifyBody.py
El funcionamiento de este último método es el siguiente: primero prepara el
HTML estático que insertará, luego coge el RDF obtenido y lo convierte en un grafo
para luego guardarlo en la carpeta uploads/tmp en formato SVG. A continuación
guardará en atributo todo el HTML.
Para el parsing de GRDDL se han creado varios métodos que son utilizados
por otros métodos anteriores aquí expuestos.
def _checkGRDDL(self):
"""
Checks if the document(HTML) has GRDDL
"""
PROYECTO FIN DE CARRERA
97
#rel="transformation" href=
regularExpressionIn = ' +rel *= *" *transformation *" *href
*='
reg = re.compile(regularExpressionIn)
aux = reg.findall(self.body)
#if is GRDDL then parse
if len(aux) > 0:
return True
else:
return False
def _parseGRDDL(self):
"""
Checks if the document(HTML) has GRDDL and if it has, then
parse to
extract the RDF in XML format
"""
#if is GRDDL then parse
if self._checkGRDDL():
parser = RDF.Parser(name='grddl')
stream = parser.parse_string_as_stream(self.body,
self.proxied_url)
return unicode(rdf.serialize_stream(stream), "utf-8",
errors='replace')
else:
#return None
return 'No GRDDL in this html....'
Código 6-28: Métodos para parser GRDDL en ModifyBody.py
Por último, se muestra el bloque de código perteneciente al método de edición
del cuerpo HTML. Como se ha mencionado más adelante, este método es el que hace
uso de todos los métodos expuestos hasta ahora.
def _modify_HTML_body(self):
pattBodyStart = '<body[\w"= ]*>'
pattBodyFinish = '</body>'
regexBodyStart = re.search(pattBodyStart, self.body)
regexBodyFinish = re.search(pattBodyFinish, self.body)
mainPageBody = self.body[regexBodyStart.end(0):
regexBodyFinish.start(0)]
#Tab creation (All, XML and GRDDL, the contentn of the tab
and the declaration)
#tab variable is a tuple with the declarations [0] and the
content of the tabs [1]
tabs = self._createTabs()
#add the declaration of the tabs
initHTML= """
<div id="homeLink"><a href="/"><img
6. DESARROLLO
98
id="homeButton" src="/static/img/home.png" alt="Return
Home"/></a></div>
<div id="tabs">
<ul>"""+ tabs[0] +"""
</ul>
<div id="fragment-web">"""
endMainTab= """
</div>
"""
finHTML="""
<script
type="text/javascript">SyntaxHighlighter.all()</script>
</div>
"""
#Last string creation (now we are goint to use the tab
content)
stringsForHTML = [initHTML, mainPageBody, endMainTab,
tabs[1], finHTML]
final = ''
#convert all to unicode(if they are unicode already
exception will be catch and wouldn't be done nothing)
for string in stringsForHTML:
try:
string = unicode(string, "utf-8", errors='replace')
except:
pass
final = final + string
self.body = self.body[: regexBodyStart.end(0)] + final +
self.body[regexBodyFinish.start(0):]
Código 6-29: Método que modifica el cuerpo del HTML en ModifyBody.py
6.2 API
Como se ha estado comentando varias veces durante esta sección de la
documentación, el proyecto incluye una API con la que trabaja, y que por tanto, es
necesario implementarla para que los scripts funcionen. La API se divide en dos
partes: la primera, es la API que se debe implementar en los scripts para que el proxy
pueda ejecutarlos y la segunda, son los métodos que tiene la API como apoyo para
usar con los ficheros RDFs, la base de datos, etc.
A continuación se explicarán los métodos de la API y a qué módulos
pertenecen.
6.2.1 ModifyBodyBase
ModifyBodyBase es una clase abstracta que está implementada en
scripts/ModifyBodyBase.py. Esta clase se debe reimplementar, ya que por
defecto está vacía (de ahí que sea abstracta), no pudiéndose crear instancias de la
PROYECTO FIN DE CARRERA
99
misma. Se deben implementar los getter y setters, constructores y el método que
ejecutará el proxy, que será el que trabaje con el HTML.
import abc
class ModifyBodyBase(object):
__metaclass__ = abc.ABCMeta
@abc.abstractmethod
def __init__(self, body, headers, proxied_url):
return
@abc.abstractmethod
def body_modification_logic(self):
"""Gets the body from an HTML request and applys any logic
to
modify, after the method returns the modified body"""
return
@abc.abstractproperty
def body(self):
return 'body: nothing to see here, move along...'
@body.setter
def body(self, newBody):
return
@abc.abstractproperty
def headers(self):
return 'headers: nothing to see here, move along...'
@headers.setter
def headers(self, newHeaders):
return
@abc.abstractproperty
def proxied_url(self):
return 'proxied_url: nothing to see here, move along...'
@proxied_url.setter
def proxied_url(self, newProxied_url):
return
Código 6-30: ModifyBodyBase.py
Este código corresponde a la clase abstracta implementada en la API de la cual
hay que heredar y reimplementar. A modo de ejemplo, a continuación se muestra una
reimplementación simple de dicha clase, la cual lo único que hace es cambiar la
palabra nothing por something.
import abc
from scripts.ModifyBodyBase import ModifyBodyBase
6. DESARROLLO
100
from django.conf import settings
class ModifyBody(ModifyBodyBase):
def __init__(self, body, headers, proxied_url):
self.body = body
self.headers = headers
self.proxied_url = proxied_url
@property
def proxied_url(self):
return self._proxied_url
@proxied_url.setter
def proxied_url(self, newProxied_url):
self._proxied_url = newProxied_url
@property
def body(self):
return self._body
@body.setter
def body(self, newBody):
self._body = newBody
@property
def headers(self):
return self._headers
@headers.setter
def headers(self, newHeaders):
self._headers = newHeaders
def body_modification_logic(self):
#we will work with utf8
self.body = unicode(self.body, "utf-8", errors='replace')
self.body = self.body.replace('nothing', 'something')
Código 6-31: Reimplementación simple para un script del proxy
6.2.2 Utilidades
A lo largo de la documentación se ha hablado muchas veces de los métodos o
funciones de apoyo que tiene la API. Estos se encuentran en la carpeta /utils y se
dividen en 3 simples módulos
Db: Tiene todo lo relacionado con los métodos relacionados con la base de
datos.
Rdf: Tiene todo lo relacionado con los RDF y metadatos.
Utils: Tiene otras funciones.
PROYECTO FIN DE CARRERA
101
6.2.2.1 Db
Para importar todos los métodos del módulo Db basta con poner lo siguiente en
el código que se esté escribiendo:
from utils.db import *
Código 6-32: Importar métodos del módulo Db
Los métodos de los que dispone este módulo son estos:
create_mysql_db(user, password, db): Crea una base de datos MySQL.
Como parámetros, recibe el usuario y password que creará la base de datos y
el nombre que se le dará a ésta última. No devuelve nada.
connect_librdf_mysql(user, password, db): Conecta LibRDF con la base de
datos para poder usarla posteriormente. Como parámetros recibe la base de
datos a la que conectarse y el usuario y password con los que realizar la
conexion. Devuelve un objeto de tipo storage (RDF.Storage)
store_RDF(rdfPath, user, password, db): Guarda en la base de datos un
RDF. Como parámetros recibe el usuario y password con los que conectarse,
la base de datos en la que se guardará el RDF y la localización del RDF. No
devuelve nada.
sparql_query(query, user, password, db, output=None): Ejecuta una
consulta SPARQL en una base de datos. Como parámetros recibe, la query
SPARQL a ejecutar, el usuario y password con los que se conectara a la base
de datos, la base de datos en la que se ejecutará la query y por último, el tipo
de formato en el que se devolverá el resultado (por defecto RDF/XML).
6.2.2.2 RDF
Para importar todos los métodos del módulo Rdf bastaría con poner lo siguiente
en el código que se esté escribiendo:
from utils.rdf import *
Código 6-33: Importar métodos del módulo Rdf
Los métodos de los que dispone este módulo son estos:
download_rdf_file(url, destination): Descarga un fichero RDF desde una
URL. Como parámetros recibe el link (URL) que apunta al fichero RDF y la ruta
donde deberá guardarse el archivo. No devuelve nada.
parse_link(link, parserType='rdfxml'): Analiza (parsea) un link RDF y
devuelve un objeto stream (objeto que devuelven los parsers) con los datos del
6. DESARROLLO
102
RDF. Como parámetros recibe la URL donde apunta el link y el tipo de formato
del RDF para usar el parser (pueden ser de varios tipos los parsers: rdfxml,
ntriples, turtle, trig, guess, rss-tag-soup, rdfa, nquads, grddl…).
parse_string(rdfStr, uri, parserType='rdfxml'): Al igual que el método
anterior, éste hace lo mismo pero en vez de pasarle un link, se le pasa un
string y una URI. La URI es necesaria para parsear un string. Si no se dispone
de una, se podrá inventarla.
serialize_stream(stream, serializerType='rdfxml'): Convierte un objeto
stream (objeto que devuelven los parsers) a otro formato soportado (rdfxml,
rdfxml-abbrev, turtle, ntriples, rss-1.0, dot, html, json, atom, nquads). Recibe
como argumentos el stream y el tipo al que se convertirá el resultado (por
defecto usa RDF/XML). Devuelve un string con el formato deseado.
str_to_graph_file(rdfString, uri, storePath, fileType='png'): Convierte un
string de RDF a un grafo, el cual será guardado como imagen. Como
parámetros recibe el string RDF, una URI necesaria (al igual que en
parse_string), la ruta donde guardar la imagen del grafo y por último, el formato
de imagen que por defecto será PNG (aunque en el proyecto se usa SVG). No
devuelve nada.
rdf_to_graph_file(rdfLink, storePath, fileType='png'): Este método hace
exactamente lo mismo que str_to_graph_file pero en vez de pasarle un string y
una URI, le pasamos una URL de un archivo RDF.
rdf_to_graph_str(rdfLink): Al igual que el método anterior, éste pasa un link a
grafo pero lo hace en formato SVG, devolviendo el string correspondiente al
archivo SVG. Por tato, no lo guarda ningún archivo en el disco duro como
sucedía en los dos métodos anteriores.
6.2.2.3 Utils
Para importar todos los métodos del módulo Utils bastaría con poner lo
siguiente en el código que se esté escribiendo:
from utils.utils import *
Código 6-34: Importar métodos del módulo utils
Los métodos de los que dispone este módulo son estos:
download_file(url, destination): Descarga un archivo y lo guarda en la ruta
que se le especifique. Como parámetros recibe la URL del archivo que debe
descargar y la ruta donde deberá guardarlo. No devuelve nada.
find_in_list(list, key): Busca en una lista una palabra y devuelve la ubicación
en forma de entero. Como parámetros recibe la lista donde debe buscar y la
clave por la que tiene que buscar. Devuelve un entero con la posición en la que
se encuentra dicha clave.
PROYECTO FIN DE CARRERA
103
7. USOS ALTERNATIVOS
Como ya se ha comentado, debido a la flexibilidad de esta herramienta, esto
hace posible usos alternativos que no tienen que ver con los metadatos. Ya se han
expuesto previamente en el punto 6.1.3, a modo de ejemplo varios scripts que
demuestran dichos usos diferentes. Estos scripts que usa el proxy están puramente
desarrollados en lenguaje Python, pudiendo hacer uso de toda la potencia del lenguaje
y de sus bibliotecas. Esto hace que las alternativas de uso que el proxy puede otorgar
sean bastante amplias. A continuación se mencionarán algunos ejemplos de ellos.
7.1 TRADUCCIÓN
Un posible uso diferente al de manipulación de metadatos podría ser la
traducción de una página web. Por jemplo, se podría hacer que una página web en
concreto estuviera como proxy en la herramienta varias veces. Cada enlace proxy,
cada uno con su propio script correspondiente, traduciría la página a un idioma
diferente.
Esto significa que el cliente pediría la página al proxy, el proxy obtendría la
página original, luego le aplicaría la traducción mediante los scripts y posteriormente
se la devolvería al cliente traducida a modo de proxy.
7.1.1 Google API
Para esto, se hicieron pruebas con la API de Google. Sin embargo, desde
Mayo del 2011 Google ha puesto una serie de impedimentos al uso de su API, ya que
la gente hacia un uso abusivo se éste servicio. Debido a esto, han limitado el número
de caracteres a la hora de traducir textos (más concretamente, 100000
caracteres/día).
Para poder obtener acceso al servicio se debe pedir una clave a Google. Esa
clave se puede obtener en la siguiente dirección:
https://code.google.com/apis/console/ . Una vez otorgada, con ella se puede acceder a
la API de todos los servicios que ofrece Google tales como Googlemaps, Buzz, URL
Shortener...
7. USOS ALTERNATIVOS
104
Ilustración 7-1: Clave de la API de Google
Ilustración 7-2: Panel de control de API de Google
PROYECTO FIN DE CARRERA
105
7.2 DISCAPACITADOS
Actualmente existen páginas que no respetan los estándares que la Web ha
creado para que personas con discapacidad puedan acceder a ella y usarla
(http://www.w3c.es/divulgacion/guiasbreves/accesibilidad).
El servidor proxy podría ayudar a webs que no respetan esta accesibilidad, a
hacerla más amigable y usable para este tipo de personas. Es cierto que parte de esta
ayuda está relacionada con los metadatos, por lo cual el proyecto estaría más
orientado a estos usos alternativos más que a los otros que se nombran más adelante
o que ya se han nombrado.
7.3 ANALIZADOR DE CÓDIGO MALICIOSO
Actualmente, existen páginas web que no son del todo fiables. Incluso algunas
no parecen fiables, y sí lo son, o por el contrario, otras páginas que sí parecen fiables
y en realidad no lo son.
Mediante un script se podría cambiar el comportamiento del proxy para que
analizase todo el código HTML en busca de incoherencias o anomalías. De esta
forma, si encontrase alguna (pese a que esta no fuese exactamente código malicioso),
podría hacer que el código HTML que se devolviera al cliente, fuera una especie de
aviso advirtiendo de que posiblemente la página no sea del todo fiable.
El gran problema de esta utilidad sin embargo, es cómo analizar el HTML. Por
un lado, se deberían de poder detectar patrones típicos como inclusión de ejecutables
con nombres de librerías o nombres de archivos del sistema, links a URLs poco
fiables, etc. Incluso se podría tener una lista negra en la cual el script del proxy pudiera
mirar si existe el link de la página de la que está haciendo de proxy.
7.4 GUARDAR DATOS
Otro de los usos posibles, podría ser el de guardado de datos. Esto podría
hacerse de muchas formas, como por ejemplo haciendo que los datos fuesen
guardados en varios tipos de recursos:
Base de datos
Texto plano
Remotamente
7. USOS ALTERNATIVOS
106
Una inserción en la base de datos mediante un script en Python podría ser tan
simple como crear unos métodos que creasen una base de datos (si no estuviese ya
creada), creando un esquema en esa base de datos, realizando posteriormente
inserciones y modificaciones en las tablas pertinentes.
En cuanto al guardado en texto plano, su realización sería tan fácil como crear
y abrir un fichero en forma de escritura, guardar ahí los datos que se deseasen y tras
finalizar el script, guardar y cerrar ese fichero.
Por último, en cuanto a la forma remota de guardado de datos, ésta sería más
laboriosa y requeriría más desarrollo que las anteriores, ya que no depende tan sólo
del script sino que también de la parte receptora de los datos. No obstante, el
funcionamiento sería bastante sencillo: cuando se desease guardar algún dato
remotamente, el script debería realizar alguna llamada remota mediante diferentes
tipos de librarías como puede ser Urlib2 de Python, haciendo que la parte receptora
los guardase.
Además de lo comentado, también se podría utilizar tecnologías como CORBA
para pasar los objetos Python usados a otro servidor, de modo que ese otro servidor
hiciera uso de los objetos obtenidos del script que hace de proxy.
7.5 NOTIFICACIONES
Cuando hablamos de notificaciones nos referimos a algo tan simple como son
los eventos. Más concretamente, cuando la página pasase por el script, éste ejecutaría
una serie de eventos a modo de notificaciones de aquello que se desee. Estas
notificaciones podrían ser de diferentes tipos:
7.5.1 Redes sociales
Por ejemplo, cuando un cliente pidiese una página, el script podría enviar un
tweet o poner un mensaje en su muro de Facebook o Google+.
7.5.2 E-mails
De la misma forma que con las redes sociales, la notificación podría ser
mediante una cuenta de correo preconfigurada en el script, a la que se mandarían los
correos, con mensajes específicos como la hora en la que se ha accedido, a que
página se ha accedido, etc.
PROYECTO FIN DE CARRERA
107
7.5.3 SMS
Una forma de tener un control constante sería con el envío de SMS. La
tecnología para enviar SMS desde un programa, está disponible desde ya hace un
tiempo.
7.6 TESTEO DE PÁGINAS WEB
Quizás esta última alternativa a la función original del proxy sea la más
llamativa para desarrolladores de páginas web, principalmente porque en ocasiones
no se tiene acceso a una infraestructura completa en la que poder hacer pruebas con
las páginas web. Por ello hacer pruebas que son posibles en tiempo real podrían ser
realizadas mediante esta herramienta. A priori, las dos situaciones más comunes
serían las siguientes:
7.6.1 Diseño
En ocasiones, los diseñadores suelen querer cambiar el diseño de una web por
las razones que sean. Sin embargo, para hacer las pruebas quizás necesiten una
infraestructura que no disponen o a la que no tienen acceso. Es entonces cuando este
proyecto entra en juego. Por ejemplo, si se desearían cambiar las imágenes, el CSS o
incluso añadir elementos JavaScript podrían ver el resultado sin tocar nada de la
página original y después de ver el resultado dependiendo de cómo sea el aspecto
resultante, establecerlo a la página original.
7.6.2 Actualizaciones
Muchas veces las páginas web necesitan ser actualizadas, ya sea por nuevos
estándares que hay que seguir/aplicar o por versiones nuevas de herramientas
usadas, como pueden ser las librerías de Google o jQuery. Generalmente, estas
actualizaciones de herramientas y estándares rompen el aspecto o incluso la
funcionalidad de la página a la que se le aplican. Esta hermmaienta podría usarse
como entorno de prueba para realizar las modificaciones necesarias hasta lograr
incorporar adecuadamente dichos elementos a la página web, recuperando su
funcionalidad y aspectos originales. Por tanto, el poder llevar a cabo las pruebas en un
entorno “sandbox” sin que afecte a la página original puede resultar de ayuda.
PROYECTO FIN DE CARRERA
109
8. CONCLUSIONES
8.1 OBJETIVOS ALCANZADOS
Pese al poco tiempo disponible para el proyecto, la mayoría de los objetivos
han sido alcanzados satisfactoriamente. Sin embargo, esto no quita que se pueda
mejorar o que queden cosas por hacer. Como ocurre casi siempre, un proyecto nunca
está del todo terminado, siempre hay cosas por añadir o mejorar. De todos modos en
este caso, se podría decir que se ha obtenido una herramienta bastante completa.
Los objetivos alcanzados han sido principalmente los descritos en el punto 2.1.
Sin embargo, a continuación se describen, sin entrar en muchos tecnicismos, algunos
que consideramos de los más importantes:
Desarrollar el proyecto al 100% con tecnologías nuevas para nosotros.
Desarrollar el proyecto al 100% con tecnologías nuevas y en auge.
Hacer una herramienta flexible de forma que no valga sólo para un campo en
especial.
Conocer la Web Semántica y sus utilidades.
Conseguir crear una API que sea posible implementar y utilizar posteriormente.
Crear un portal web llamativo y fácil de manejar.
8.2 CONSIDERACIONES
Como ya hemos comentado con anterioridad, son diversas las cosas que
hemos aprendido y manejado gracias a este proyecto: nuevos lenguajes de
programación, frameworks, librerías, tecnologías, términos, estructuras, etc. No
obstante, esto ha llevado a que tardáramos más tiempo en su desarrollo y finalización,
ya que el aprendizaje y formación requieren muchísimo tiempo.
Asimismo, también hemos tendio que realizar algunos trabajos extra que no
tenían que ver con el proyecto directamente. Por ejemplo, para probar el GRDDL
tuvimos que modificar una parte de la página personal de Diego López de Ipiña. Esta
taréa se realizó satisfactoriamente y como se puede ver en el manual17, los metadatos
pueden ser extraidos mediante GRDDL.
17
Ver punto 13 para consultar el manual.
8. CONCLUSIONES
110
Además de eso, tuvimos que crear un método en la librería Redland, más
concretamente en las bindings de Python18. Posteriormente, este método se añadió a
su repositorio oficial de Github (https://github.com/dajobe/redland-bindings/pull/2).
En cuanto a las tecnologías que hemos aprendido durante todo este tiempo,
algunas de ellas son las siguientes:
Python
Django
Web Semántica
RDF
OWL
SPARQL
Expresiones regulares en Python
Git
También, cabe destacar que todo este tiempo no hemos trabajado mucho con
control de versiones, y si lo hemos hecho ha sido con SVN. Esto ha cambiado la forma
en que programábamos, ya que había que aplicar una estrategía o planificación para
que cuando cada uno de nosotros implementase características por separado, al hacer
un merge de cada cambio que hiciéramos por separado, no se creasen conflictos
difíciles de resolver. Por otra parte, Git está diseñado de tal forma que el mezclado o
merge de ramas y cambios realizados en el repositorio por diferentes personas
simultáneamente sea poco engorroso y problemático.
Por otro lado, nos gustaría comentar que estamos encantados con el potencial
que ofrece Python, lo rápido que se puede poner en marcha y lo flexible que es.
Además, pese a que se trata de un lenguaje interpretado, si éste se compila, es muy
rápido.
En cuanto al entorno de producción, en su momento se decidió ponerlo con
Nginx porque es un servidor bastante liviano, rápido y muy configurable. Esto nos ha
llevado a aprender a configurar un servidor Nginx para aplicaciones Django mediante
uWSGI.
Por tanto, en general, estamos muy contentos de haber podido realizar este
proyecto y presentarlo como Proyecto de Fin de Carrera.
8.3 POSIBLES MEJORAS FUTURAS
Las posibles mejoras futuras que se pueden realizar en este proyecto son
diversas. Como en todo proyecto sucede, nunca se llega a un final en el que la
18
Ver punto 5.2.4.4 para más información sobre las Bindings de Python de Redland.
PROYECTO FIN DE CARRERA
111
herramienta queda completamente terminada; siempre hay algún bug que resolver o
característica que mejorar o añadir.
En primer lugar, se deberían mejorar las codificaciones HTML. Pese a que la
culpa no sea del proyecto en sí, éste debería saber trabajar mejor con las
codificaciones. De todos modos, cabe mencionar que ya intenta resolver este
problema de alguna forma, pero sin embargo, esto se podría mejorar.
Otra cosa a mejorar es la disminución del número de dependencias que
necesita el proyecto para ponerlo en marcha. Se trata sin duda alguna de algo
bastante complicado, ya que para ello habría que rehacer muchas cosas, invirtiendo
esfuerzo en algo que ya está hecho.
Por otro lado, estaría la cuestión de la verificación de archivos. Cuando
subimos un script o un RDF al servidor proxy, la página que está a cargo de
descargarse o subir ese archivo al servidor debería de comprobar que ese fichero
subido o descargado es del tipo que dice ser.
Por otra parte, también se podría mejorar la herramienta de consultas SPARQL
con un pequeño wizard o asistente, que permitiera realizar éstas de manera sencilla y
visual con sólo hacer unos clicks en ciertos elementos visuales, haciendo que la
sentencia a la consulta SPARQL correspondiente se generase sola.
Es más, también se podría habilitar una cache en el proxy. Esto haría que
algunas de las peticiones fuesen más rápidas, ya que se encontrarían previamente en
ese cache.
En cuanto a los idiomas, se podría incluir una selección de idioma a la página
principal del portal. Actualmente, el proyecto se encuentra únicamente disponible en
inglés. Django para ello dispone de una característica muy fácil de usar basada en
ficheros donde se leen y se obtienen los strings asociados a identificativos específicos.
Asimismo, también se podría habilitar algún mecanismo que permitiera poder
cambiar el tema de la página principal. Sin embargo, esto sería algo más complicado.
Si fuesen temas o estilos similares no habría tanto problema, ya que se podrían
reutilizar los CSS, pero cambiar los temas dinámicamente y que sean totalmente
diferentes traería consigo bastante trabajo. Aún así, existen plugins para Django con la
capacidad de hacer esto más facilmente.
Por último, cabe mencionar que también se podría añadir al manual de usuario
una pequeña guía de cómo poner en producción esta herramienta para servidores
como Apache o Cherokee además de para Nginx.
PROYECTO FIN DE CARRERA
113
9. AGRADECIMIENTOS
Este proyecto no podría haberse hecho realidad sin muchas de las personas,
grupos u organizaciones, con o sin conocimiento de lo que estábamos desarrollando.
Por ello, desde nuestro más sincero agradecimiento les dedicamos una pequeña
porción de la documentación exclusivamente a todos ellos:
Diego López de Ipiña: Nuestro Director de proyecto y el precursor de éste,
que sin sus ideas y consejos no hubiese sido posible su realización.
Familiares, compañeros y amigos: Ese grupo de personas, a veces pequeño
y otras grande, ofrecen apoyo incondicional en todo momento, haciendo que
los momentos difíciles y complicados lo sean menos.
Software Libre: Ese gran movimiento que hace que toda la cultura, la justicia,
el equilibrio y la evolución tecnológica sean algo de lo que todos nos podamos
beneficiar, ayudando a la gente en muchas cosas como por ejemplo, en la
realización de este proyecto.
Richard (RMS) Stallman: Por crear el movimiento del software libre del que
cada vez más gente es parte y hacer que el desarrollo de software, cultura,
hardware, etc. pueda crecer mucho más en el futuro.
Autores de todos los recursos y herramientas utilizadas: Sería imposible
agradecer a todos y cada uno de los autores y autoras de las librerías,
lenguajes, frameworks, programas, SOs, etc. de los que hemos hecho uso para
llevar a cabo este proyecto. Pese a ello, generalizaremos y les agradecemos
enorme y sinceramente el esfuerzo realizado, ya que sin sus herramientas no
habría sido posible la realización de este proyecto.
Como a veces ocurre, lo más probable es que nos dejemos a alguien más por
mencionar, pero eso no significa que no agradezcamos su apoyo y/o trabajo pese a no
haber sido plasmado en esta pequeña sección.
Por último, decir que si alguna pieza de este gran engranage de recursos que
conforman el proyecto hubiese fallado, éste no podría haber sido posible y por eso va
dedicado a todos ellos en su totalidad.
Muchas gracias a todos y a todas.
PROYECTO FIN DE CARRERA
115
10. LICENCIAS
Este proyecto está sujeto a varias licencias. Salvo que se especifique lo
contrario los autores respectivos de las licencias son:
(2011) Xabier (sLoK) Larrakoetxea <[email protected]>
(2011) Iraide (Sharem) Diaz <[email protected]>
10.1 IMÁGENES
Las imágenes de esta documentación pertenecen a sus respectivos dueños y
licencias. Este documento no altera las licencias de las fotos. Si alguno de los autores
de las fotos está en contra de su publicación deberá notificarlo para su posterior
eliminación del documento. Dirección de contacto:
10.2 DOCUMENTACIÓN
La presente documentación está licenciada bajo Creative Commons:
Attribution-ShareAlike 3.0 Unported (CC BY-SA 3.0):
http://creativecommons.org/licenses/by-sa/3.0/
License
THE WORK (AS DEFINED BELOW) IS PROVIDED UNDER THE TERMS OF
THIS CREATIVE COMMONS PUBLIC LICENSE ("CCPL" OR "LICENSE"). THE
WORK IS PROTECTED BY COPYRIGHT AND/OR OTHER APPLICABLE LAW.
ANY USE OF THE WORK OTHER THAN AS AUTHORIZED UNDER THIS
LICENSE OR COPYRIGHT LAW IS PROHIBITED.
BY EXERCISING ANY RIGHTS TO THE WORK PROVIDED HERE, YOU
ACCEPT AND AGREE TO BE BOUND BY THE TERMS OF THIS LICENSE. TO
THE EXTENT THIS LICENSE MAY BE CONSIDERED TO BE A CONTRACT,
THE LICENSOR GRANTS YOU THE RIGHTS CONTAINED HERE IN
CONSIDERATION OF YOUR ACCEPTANCE OF SUCH TERMS AND
CONDITIONS.
1. Definitions
10. LICENCIAS
116
a. "Adaptation" means a work based upon the Work, or upon the Work and other pre-existing works, such as a translation, adaptation, derivative work, arrangement of music or other alterations of a literary or artistic work, or phonogram or performance and includes cinematographic adaptations or any other form in which the Work may be recast, transformed, or adapted including in any form recognizably derived from the original, except that a work that constitutes a Collection will not be considered an Adaptation for the purpose of this License. For the avoidance of doubt, where the Work is a musical work, performance or phonogram, the synchronization of the Work in timed-relation with a moving image ("synching") will be considered an Adaptation for the purpose of this License.
b. "Collection" means a collection of literary or artistic works, such as encyclopedias and anthologies, or performances, phonograms or broadcasts, or other works or subject matter other than works listed in Section 1(f) below, which, by reason of the selection and arrangement of their contents, constitute intellectual creations, in which the Work is included in its entirety in unmodified form along with one or more other contributions, each constituting separate and independent works in themselves, which together are assembled into a collective whole. A work that constitutes a Collection will not be considered an Adaptation (as defined below) for the purposes of this License.
c. "Creative Commons Compatible License" means a license that is listed at http://creativecommons.org/compatiblelicenses that has been approved by Creative Commons as being essentially equivalent to this License, including, at a minimum, because that license: (i) contains terms that have the same purpose, meaning and effect as the License Elements of this License; and, (ii) explicitly permits the relicensing of adaptations of works made available under that license under this License or a Creative Commons jurisdiction license with the same License Elements as this License.
d. "Distribute" means to make available to the public the original and copies of the Work or Adaptation, as appropriate, through sale or other transfer of ownership.
e. "License Elements" means the following high-level license attributes as selected by Licensor and indicated in the title of this License: Attribution, ShareAlike.
f. "Licensor" means the individual, individuals, entity or entities that offer(s) the Work under the terms of this License.
g. "Original Author" means, in the case of a literary or artistic work, the individual, individuals, entity or entities who created the Work or if no individual or entity can be identified, the publisher; and in addition (i) in the case of a performance the actors, singers, musicians, dancers, and other persons who act, sing, deliver, declaim, play in, interpret or otherwise perform literary or artistic works or expressions of folklore; (ii) in the case of a phonogram the producer being the person or legal entity who first fixes the sounds of a performance or other sounds; and, (iii) in the case of broadcasts, the organization that transmits the broadcast.
h. "Work" means the literary and/or artistic work offered under the terms of this License including without limitation any production in the literary, scientific and artistic domain, whatever may be the mode or form of its expression including digital form, such as a book, pamphlet and other writing; a lecture, address, sermon or other work of the same nature; a dramatic or dramatico-musical work; a choreographic work or entertainment in dumb show; a musical composition with or without words; a cinematographic work to which are assimilated works expressed by a process analogous to cinematography; a work of drawing, painting, architecture, sculpture, engraving or lithography; a photographic work to which are assimilated works expressed by a process analogous to photography; a work of applied art; an illustration, map, plan, sketch or three-dimensional work relative to geography, topography, architecture or science; a performance; a broadcast; a phonogram; a compilation of data to the extent it is protected as a copyrightable work; or a work performed by a variety or circus performer to the extent it is not otherwise considered a literary or artistic work.
i. "You" means an individual or entity exercising rights under this License who has not previously violated the terms of this License with respect to the Work, or who has received express permission from the Licensor to exercise rights under this License despite a previous violation.
PROYECTO FIN DE CARRERA
117
j. "Publicly Perform" means to perform public recitations of the Work and to communicate to the public those public recitations, by any means or process, including by wire or wireless means or public digital performances; to make available to the public Works in such a way that members of the public may access these Works from a place and at a place individually chosen by them; to perform the Work to the public by any means or process and the communication to the public of the performances of the Work, including by public digital performance; to broadcast and rebroadcast the Work by any means including signs, sounds or images.
k. "Reproduce" means to make copies of the Work by any means including without limitation by sound or visual recordings and the right of fixation and reproducing fixations of the Work, including storage of a protected performance or phonogram in digital form or other electronic medium.
2. Fair Dealing Rights. Nothing in this License is intended to reduce, limit, or restrict
any uses free from copyright or rights arising from limitations or exceptions that are
provided for in connection with the copyright protection under copyright law or other
applicable laws.
3. License Grant. Subject to the terms and conditions of this License, Licensor hereby
grants You a worldwide, royalty-free, non-exclusive, perpetual (for the duration of the
applicable copyright) license to exercise the rights in the Work as stated below:
a. to Reproduce the Work, to incorporate the Work into one or more Collections, and to Reproduce the Work as incorporated in the Collections;
b. to create and Reproduce Adaptations provided that any such Adaptation, including any translation in any medium, takes reasonable steps to clearly label, demarcate or otherwise identify that changes were made to the original Work. For example, a translation could be marked "The original work was translated from English to Spanish," or a modification could indicate "The original work has been modified.";
c. to Distribute and Publicly Perform the Work including as incorporated in Collections; and,
d. to Distribute and Publicly Perform Adaptations.
e. For the avoidance of doubt: i. Non-waivable Compulsory License Schemes. In those jurisdictions in which
the right to collect royalties through any statutory or compulsory licensing scheme cannot be waived, the Licensor reserves the exclusive right to collect such royalties for any exercise by You of the rights granted under this License;
ii. Waivable Compulsory License Schemes. In those jurisdictions in which the right to collect royalties through any statutory or compulsory licensing scheme can be waived, the Licensor waives the exclusive right to collect such royalties for any exercise by You of the rights granted under this License; and,
iii. Voluntary License Schemes. The Licensor waives the right to collect royalties, whether individually or, in the event that the Licensor is a member of a collecting society that administers voluntary licensing schemes, via that society, from any exercise by You of the rights granted under this License.
The above rights may be exercised in all media and formats whether now known or
hereafter devised. The above rights include the right to make such modifications as are
technically necessary to exercise the rights in other media and formats. Subject to
Section 8(f), all rights not expressly granted by Licensor are hereby reserved.
4. Restrictions. The license granted in Section 3 above is expressly made subject to and
limited by the following restrictions:
10. LICENCIAS
118
a. You may Distribute or Publicly Perform the Work only under the terms of this License. You must include a copy of, or the Uniform Resource Identifier (URI) for, this License with every copy of the Work You Distribute or Publicly Perform. You may not offer or impose any terms on the Work that restrict the terms of this License or the ability of the recipient of the Work to exercise the rights granted to that recipient under the terms of the License. You may not sublicense the Work. You must keep intact all notices that refer to this License and to the disclaimer of warranties with every copy of the Work You Distribute or Publicly Perform. When You Distribute or Publicly Perform the Work, You may not impose any effective technological measures on the Work that restrict the ability of a recipient of the Work from You to exercise the rights granted to that recipient under the terms of the License. This Section 4(a) applies to the Work as incorporated in a Collection, but this does not require the Collection apart from the Work itself to be made subject to the terms of this License. If You create a Collection, upon notice from any Licensor You must, to the extent practicable, remove from the Collection any credit as required by Section 4(c), as requested. If You create an Adaptation, upon notice from any Licensor You must, to the extent practicable, remove from the Adaptation any credit as required by Section 4(c), as requested.
b. You may Distribute or Publicly Perform an Adaptation only under the terms of: (i) this License; (ii) a later version of this License with the same License Elements as this License; (iii) a Creative Commons jurisdiction license (either this or a later license version) that contains the same License Elements as this License (e.g., Attribution-ShareAlike 3.0 US)); (iv) a Creative Commons Compatible License. If you license the Adaptation under one of the licenses mentioned in (iv), you must comply with the terms of that license. If you license the Adaptation under the terms of any of the licenses mentioned in (i), (ii) or (iii) (the "Applicable License"), you must comply with the terms of the Applicable License generally and the following provisions: (I) You must include a copy of, or the URI for, the Applicable License with every copy of each Adaptation You Distribute or Publicly Perform; (II) You may not offer or impose any terms on the Adaptation that restrict the terms of the Applicable License or the ability of the recipient of the Adaptation to exercise the rights granted to that recipient under the terms of the Applicable License; (III) You must keep intact all notices that refer to the Applicable License and to the disclaimer of warranties with every copy of the Work as included in the Adaptation You Distribute or Publicly Perform; (IV) when You Distribute or Publicly Perform the Adaptation, You may not impose any effective technological measures on the Adaptation that restrict the ability of a recipient of the Adaptation from You to exercise the rights granted to that recipient under the terms of the Applicable License. This Section 4(b) applies to the Adaptation as incorporated in a Collection, but this does not require the Collection apart from the Adaptation itself to be made subject to the terms of the Applicable License.
c. If You Distribute, or Publicly Perform the Work or any Adaptations or Collections, You must, unless a request has been made pursuant to Section 4(a), keep intact all copyright notices for the Work and provide, reasonable to the medium or means You are utilizing: (i) the name of the Original Author (or pseudonym, if applicable) if supplied, and/or if the Original Author and/or Licensor designate another party or parties (e.g., a sponsor institute, publishing entity, journal) for attribution ("Attribution Parties") in Licensor's copyright notice, terms of service or by other reasonable means, the name of such party or parties; (ii) the title of the Work if supplied; (iii) to the extent reasonably practicable, the URI, if any, that Licensor specifies to be associated with the Work, unless such URI does not refer to the copyright notice or licensing information for the Work; and (iv) , consistent with Ssection 3(b), in the case of an Adaptation, a credit identifying the use of the Work in the Adaptation (e.g., "French translation of the Work by Original Author," or "Screenplay based on original Work by Original Author"). The credit required by this Section 4(c) may be implemented in any reasonable manner; provided, however, that in the case of a Adaptation or Collection, at a minimum such credit will appear, if a credit for all contributing authors of the Adaptation or Collection appears, then as part of these credits and in a manner at least as prominent as the credits for the other contributing authors. For the avoidance of doubt, You may only use the credit required by this Section for the purpose of attribution in the manner set out
PROYECTO FIN DE CARRERA
119
above and, by exercising Your rights under this License, You may not implicitly or explicitly assert or imply any connection with, sponsorship or endorsement by the Original Author, Licensor and/or Attribution Parties, as appropriate, of You or Your use of the Work, without the separate, express prior written permission of the Original Author, Licensor and/or Attribution Parties.
d. Except as otherwise agreed in writing by the Licensor or as may be otherwise permitted by applicable law, if You Reproduce, Distribute or Publicly Perform the Work either by itself or as part of any Adaptations or Collections, You must not distort, mutilate, modify or take other derogatory action in relation to the Work which would be prejudicial to the Original Author's honor or reputation. Licensor agrees that in those jurisdictions (e.g. Japan), in which any exercise of the right granted in Section 3(b) of this License (the right to make Adaptations) would be deemed to be a distortion, mutilation, modification or other derogatory action prejudicial to the Original Author's honor and reputation, the Licensor will waive or not assert, as appropriate, this Section, to the fullest extent permitted by the applicable national law, to enable You to reasonably exercise Your right under Section 3(b) of this License (right to make Adaptations) but not otherwise.
5. Representations, Warranties and Disclaimer
UNLESS OTHERWISE MUTUALLY AGREED TO BY THE PARTIES IN
WRITING, LICENSOR OFFERS THE WORK AS-IS AND MAKES NO
REPRESENTATIONS OR WARRANTIES OF ANY KIND CONCERNING THE
WORK, EXPRESS, IMPLIED, STATUTORY OR OTHERWISE, INCLUDING,
WITHOUT LIMITATION, WARRANTIES OF TITLE, MERCHANTIBILITY,
FITNESS FOR A PARTICULAR PURPOSE, NONINFRINGEMENT, OR THE
ABSENCE OF LATENT OR OTHER DEFECTS, ACCURACY, OR THE PRESENCE
OF ABSENCE OF ERRORS, WHETHER OR NOT DISCOVERABLE. SOME
JURISDICTIONS DO NOT ALLOW THE EXCLUSION OF IMPLIED
WARRANTIES, SO SUCH EXCLUSION MAY NOT APPLY TO YOU.
6. Limitation on Liability. EXCEPT TO THE EXTENT REQUIRED BY
APPLICABLE LAW, IN NO EVENT WILL LICENSOR BE LIABLE TO YOU ON
ANY LEGAL THEORY FOR ANY SPECIAL, INCIDENTAL, CONSEQUENTIAL,
PUNITIVE OR EXEMPLARY DAMAGES ARISING OUT OF THIS LICENSE OR
THE USE OF THE WORK, EVEN IF LICENSOR HAS BEEN ADVISED OF THE
POSSIBILITY OF SUCH DAMAGES.
7. Termination
a. This License and the rights granted hereunder will terminate automatically upon any breach by You of the terms of this License. Individuals or entities who have received Adaptations or Collections from You under this License, however, will not have their licenses terminated provided such individuals or entities remain in full compliance with those licenses. Sections 1, 2, 5, 6, 7, and 8 will survive any termination of this License.
b. Subject to the above terms and conditions, the license granted here is perpetual (for the duration of the applicable copyright in the Work). Notwithstanding the above, Licensor reserves the right to release the Work under different license terms or to stop distributing the Work at any time; provided, however that any such election will not serve to withdraw this License (or any other license that has been, or is required to be, granted under the terms of this License), and this License will continue in full force and effect unless terminated as stated above.
8. Miscellaneous
10. LICENCIAS
120
a. Each time You Distribute or Publicly Perform the Work or a Collection, the Licensor offers to the recipient a license to the Work on the same terms and conditions as the license granted to You under this License.
b. Each time You Distribute or Publicly Perform an Adaptation, Licensor offers to the recipient a license to the original Work on the same terms and conditions as the license granted to You under this License.
c. If any provision of this License is invalid or unenforceable under applicable law, it shall not affect the validity or enforceability of the remainder of the terms of this License, and without further action by the parties to this agreement, such provision shall be reformed to the minimum extent necessary to make such provision valid and enforceable.
d. No term or provision of this License shall be deemed waived and no breach consented to unless such waiver or consent shall be in writing and signed by the party to be charged with such waiver or consent.
e. This License constitutes the entire agreement between the parties with respect to the Work licensed here. There are no understandings, agreements or representations with respect to the Work not specified here. Licensor shall not be bound by any additional provisions that may appear in any communication from You. This License may not be modified without the mutual written agreement of the Licensor and You.
f. The rights granted under, and the subject matter referenced, in this License were drafted utilizing the terminology of the Berne Convention for the Protection of Literary and Artistic Works (as amended on September 28, 1979), the Rome Convention of 1961, the WIPO Copyright Treaty of 1996, the WIPO Performances and Phonograms Treaty of 1996 and the Universal Copyright Convention (as revised on July 24, 1971). These rights and subject matter take effect in the relevant jurisdiction in which the License terms are sought to be enforced according to the corresponding provisions of the implementation of those treaty provisions in the applicable national law. If the standard suite of rights granted under applicable copyright law includes additional rights not granted under this License, such additional rights are deemed to be included in the License; this License is not intended to restrict the license of any rights under applicable law.
10.3 PROYECTO
El código fuente y el proyecto en sí están disponibles en la siguiente dirección
de Github: https://github.com/slok/metaproxy bajo licencia GPLv3.
GNU GENERAL PUBLIC LICENSE
Version 3, 29 June 2007
Copyright © 2007 Free Software Foundation, Inc. <http://fsf.org/>
Everyone is permitted to copy and distribute verbatim copies of this license document,
but changing it is not allowed.
Preamble
PROYECTO FIN DE CARRERA
121
The GNU General Public License is a free, copyleft license for software and other kinds
of works.
The licenses for most software and other practical works are designed to take away your
freedom to share and change the works. By contrast, the GNU General Public License is
intended to guarantee your freedom to share and change all versions of a program--to
make sure it remains free software for all its users. We, the Free Software Foundation,
use the GNU General Public License for most of our software; it applies also to any
other work released this way by its authors. You can apply it to your programs, too.
When we speak of free software, we are referring to freedom, not price. Our General
Public Licenses are designed to make sure that you have the freedom to distribute
copies of free software (and charge for them if you wish), that you receive source code
or can get it if you want it, that you can change the software or use pieces of it in new
free programs, and that you know you can do these things.
To protect your rights, we need to prevent others from denying you these rights or
asking you to surrender the rights. Therefore, you have certain responsibilities if you
distribute copies of the software, or if you modify it: responsibilities to respect the
freedom of others.
For example, if you distribute copies of such a program, whether gratis or for a fee, you
must pass on to the recipients the same freedoms that you received. You must make sure
that they, too, receive or can get the source code. And you must show them these terms
so they know their rights.
Developers that use the GNU GPL protect your rights with two steps: (1) assert
copyright on the software, and (2) offer you this License giving you legal permission to
copy, distribute and/or modify it.
For the developers' and authors' protection, the GPL clearly explains that there is no
warranty for this free software. For both users' and authors' sake, the GPL requires that
modified versions be marked as changed, so that their problems will not be attributed
erroneously to authors of previous versions.
Some devices are designed to deny users access to install or run modified versions of
the software inside them, although the manufacturer can do so. This is fundamentally
incompatible with the aim of protecting users' freedom to change the software. The
systematic pattern of such abuse occurs in the area of products for individuals to use,
which is precisely where it is most unacceptable. Therefore, we have designed this
version of the GPL to prohibit the practice for those products. If such problems arise
substantially in other domains, we stand ready to extend this provision to those domains
in future versions of the GPL, as needed to protect the freedom of users.
Finally, every program is threatened constantly by software patents. States should not
allow patents to restrict development and use of software on general-purpose computers,
but in those that do, we wish to avoid the special danger that patents applied to a free
10. LICENCIAS
122
program could make it effectively proprietary. To prevent this, the GPL assures that
patents cannot be used to render the program non-free.
The precise terms and conditions for copying, distribution and modification follow.
TERMS AND CONDITIONS
0. Definitions.
“This License” refers to version 3 of the GNU General Public License.
“Copyright” also means copyright-like laws that apply to other kinds of works, such as
semiconductor masks.
“The Program” refers to any copyrightable work licensed under this License. Each
licensee is addressed as “you”. “Licensees” and “recipients” may be individuals or
organizations.
To “modify” a work means to copy from or adapt all or part of the work in a fashion
requiring copyright permission, other than the making of an exact copy. The resulting
work is called a “modified version” of the earlier work or a work “based on” the earlier
work.
A “covered work” means either the unmodified Program or a work based on the
Program.
To “propagate” a work means to do anything with it that, without permission, would
make you directly or secondarily liable for infringement under applicable copyright law,
except executing it on a computer or modifying a private copy. Propagation includes
copying, distribution (with or without modification), making available to the public, and
in some countries other activities as well.
To “convey” a work means any kind of propagation that enables other parties to make
or receive copies. Mere interaction with a user through a computer network, with no
transfer of a copy, is not conveying.
An interactive user interface displays “Appropriate Legal Notices” to the extent that it
includes a convenient and prominently visible feature that (1) displays an appropriate
copyright notice, and (2) tells the user that there is no warranty for the work (except to
the extent that warranties are provided), that licensees may convey the work under this
License, and how to view a copy of this License. If the interface presents a list of user
commands or options, such as a menu, a prominent item in the list meets this criterion.
1. Source Code.
The “source code” for a work means the preferred form of the work for making
modifications to it. “Object code” means any non-source form of a work.
PROYECTO FIN DE CARRERA
123
A “Standard Interface” means an interface that either is an official standard defined by a
recognized standards body, or, in the case of interfaces specified for a particular
programming language, one that is widely used among developers working in that
language.
The “System Libraries” of an executable work include anything, other than the work as
a whole, that (a) is included in the normal form of packaging a Major Component, but
which is not part of that Major Component, and (b) serves only to enable use of the
work with that Major Component, or to implement a Standard Interface for which an
implementation is available to the public in source code form. A “Major Component”,
in this context, means a major essential component (kernel, window system, and so on)
of the specific operating system (if any) on which the executable work runs, or a
compiler used to produce the work, or an object code interpreter used to run it.
The “Corresponding Source” for a work in object code form means all the source code
needed to generate, install, and (for an executable work) run the object code and to
modify the work, including scripts to control those activities. However, it does not
include the work's System Libraries, or general-purpose tools or generally available free
programs which are used unmodified in performing those activities but which are not
part of the work. For example, Corresponding Source includes interface definition files
associated with source files for the work, and the source code for shared libraries and
dynamically linked subprograms that the work is specifically designed to require, such
as by intimate data communication or control flow between those subprograms and
other parts of the work.
The Corresponding Source need not include anything that users can regenerate
automatically from other parts of the Corresponding Source.
The Corresponding Source for a work in source code form is that same work.
2. Basic Permissions.
All rights granted under this License are granted for the term of copyright on the
Program, and are irrevocable provided the stated conditions are met. This License
explicitly affirms your unlimited permission to run the unmodified Program. The output
from running a covered work is covered by this License only if the output, given its
content, constitutes a covered work. This License acknowledges your rights of fair use
or other equivalent, as provided by copyright law.
You may make, run and propagate covered works that you do not convey, without
conditions so long as your license otherwise remains in force. You may convey covered
works to others for the sole purpose of having them make modifications exclusively for
you, or provide you with facilities for running those works, provided that you comply
with the terms of this License in conveying all material for which you do not control
copyright. Those thus making or running the covered works for you must do so
exclusively on your behalf, under your direction and control, on terms that prohibit
them from making any copies of your copyrighted material outside their relationship
with you.
10. LICENCIAS
124
Conveying under any other circumstances is permitted solely under the conditions
stated below. Sublicensing is not allowed; section 10 makes it unnecessary.
3. Protecting Users' Legal Rights From Anti-Circumvention Law.
No covered work shall be deemed part of an effective technological measure under any
applicable law fulfilling obligations under article 11 of the WIPO copyright treaty
adopted on 20 December 1996, or similar laws prohibiting or restricting circumvention
of such measures.
When you convey a covered work, you waive any legal power to forbid circumvention
of technological measures to the extent such circumvention is effected by exercising
rights under this License with respect to the covered work, and you disclaim any
intention to limit operation or modification of the work as a means of enforcing, against
the work's users, your or third parties' legal rights to forbid circumvention of
technological measures.
4. Conveying Verbatim Copies.
You may convey verbatim copies of the Program's source code as you receive it, in any
medium, provided that you conspicuously and appropriately publish on each copy an
appropriate copyright notice; keep intact all notices stating that this License and any
non-permissive terms added in accord with section 7 apply to the code; keep intact all
notices of the absence of any warranty; and give all recipients a copy of this License
along with the Program.
You may charge any price or no price for each copy that you convey, and you may offer
support or warranty protection for a fee.
5. Conveying Modified Source Versions.
You may convey a work based on the Program, or the modifications to produce it from
the Program, in the form of source code under the terms of section 4, provided that you
also meet all of these conditions:
a) The work must carry prominent notices stating that you modified it, and giving a relevant date.
b) The work must carry prominent notices stating that it is released under this License and any conditions added under section 7. This requirement modifies the requirement in section 4 to “keep intact all notices”.
c) You must license the entire work, as a whole, under this License to anyone who comes into possession of a copy. This License will therefore apply, along with any applicable section 7 additional terms, to the whole of the work, and all its parts, regardless of how they are packaged. This License gives no permission to license the work in any other way, but it does not invalidate such permission if you have separately received it.
d) If the work has interactive user interfaces, each must display Appropriate Legal Notices; however, if the Program has interactive interfaces that do not display Appropriate Legal Notices, your work need not make them do so.
PROYECTO FIN DE CARRERA
125
A compilation of a covered work with other separate and independent works, which are
not by their nature extensions of the covered work, and which are not combined with it
such as to form a larger program, in or on a volume of a storage or distribution medium,
is called an “aggregate” if the compilation and its resulting copyright are not used to
limit the access or legal rights of the compilation's users beyond what the individual
works permit. Inclusion of a covered work in an aggregate does not cause this License
to apply to the other parts of the aggregate.
6. Conveying Non-Source Forms.
You may convey a covered work in object code form under the terms of sections 4 and
5, provided that you also convey the machine-readable Corresponding Source under the
terms of this License, in one of these ways:
a) Convey the object code in, or embodied in, a physical product (including a physical distribution medium), accompanied by the Corresponding Source fixed on a durable physical medium customarily used for software interchange.
b) Convey the object code in, or embodied in, a physical product (including a physical distribution medium), accompanied by a written offer, valid for at least three years and valid for as long as you offer spare parts or customer support for that product model, to give anyone who possesses the object code either (1) a copy of the Corresponding Source for all the software in the product that is covered by this License, on a durable physical medium customarily used for software interchange, for a price no more than your reasonable cost of physically performing this conveying of source, or (2) access to copy the Corresponding Source from a network server at no charge.
c) Convey individual copies of the object code with a copy of the written offer to provide the Corresponding Source. This alternative is allowed only occasionally and noncommercially, and only if you received the object code with such an offer, in accord with subsection 6b.
d) Convey the object code by offering access from a designated place (gratis or for a charge), and offer equivalent access to the Corresponding Source in the same way through the same place at no further charge. You need not require recipients to copy the Corresponding Source along with the object code. If the place to copy the object code is a network server, the Corresponding Source may be on a different server (operated by you or a third party) that supports equivalent copying facilities, provided you maintain clear directions next to the object code saying where to find the Corresponding Source. Regardless of what server hosts the Corresponding Source, you remain obligated to ensure that it is available for as long as needed to satisfy these requirements.
e) Convey the object code using peer-to-peer transmission, provided you inform other peers where the object code and Corresponding Source of the work are being offered to the general public at no charge under subsection 6d.
A separable portion of the object code, whose source code is excluded from the
Corresponding Source as a System Library, need not be included in conveying the
object code work.
A “User Product” is either (1) a “consumer product”, which means any tangible
personal property which is normally used for personal, family, or household purposes,
or (2) anything designed or sold for incorporation into a dwelling. In determining
whether a product is a consumer product, doubtful cases shall be resolved in favor of
coverage. For a particular product received by a particular user, “normally used” refers
10. LICENCIAS
126
to a typical or common use of that class of product, regardless of the status of the
particular user or of the way in which the particular user actually uses, or expects or is
expected to use, the product. A product is a consumer product regardless of whether the
product has substantial commercial, industrial or non-consumer uses, unless such uses
represent the only significant mode of use of the product.
“Installation Information” for a User Product means any methods, procedures,
authorization keys, or other information required to install and execute modified
versions of a covered work in that User Product from a modified version of its
Corresponding Source. The information must suffice to ensure that the continued
functioning of the modified object code is in no case prevented or interfered with solely
because modification has been made.
If you convey an object code work under this section in, or with, or specifically for use
in, a User Product, and the conveying occurs as part of a transaction in which the right
of possession and use of the User Product is transferred to the recipient in perpetuity or
for a fixed term (regardless of how the transaction is characterized), the Corresponding
Source conveyed under this section must be accompanied by the Installation
Information. But this requirement does not apply if neither you nor any third party
retains the ability to install modified object code on the User Product (for example, the
work has been installed in ROM).
The requirement to provide Installation Information does not include a requirement to
continue to provide support service, warranty, or updates for a work that has been
modified or installed by the recipient, or for the User Product in which it has been
modified or installed. Access to a network may be denied when the modification itself
materially and adversely affects the operation of the network or violates the rules and
protocols for communication across the network.
Corresponding Source conveyed, and Installation Information provided, in accord with
this section must be in a format that is publicly documented (and with an
implementation available to the public in source code form), and must require no special
password or key for unpacking, reading or copying.
7. Additional Terms.
“Additional permissions” are terms that supplement the terms of this License by making
exceptions from one or more of its conditions. Additional permissions that are
applicable to the entire Program shall be treated as though they were included in this
License, to the extent that they are valid under applicable law. If additional permissions
apply only to part of the Program, that part may be used separately under those
permissions, but the entire Program remains governed by this License without regard to
the additional permissions.
When you convey a copy of a covered work, you may at your option remove any
additional permissions from that copy, or from any part of it. (Additional permissions
may be written to require their own removal in certain cases when you modify the
PROYECTO FIN DE CARRERA
127
work.) You may place additional permissions on material, added by you to a covered
work, for which you have or can give appropriate copyright permission.
Notwithstanding any other provision of this License, for material you add to a covered
work, you may (if authorized by the copyright holders of that material) supplement the
terms of this License with terms:
a) Disclaiming warranty or limiting liability differently from the terms of sections 15 and 16 of this License; or
b) Requiring preservation of specified reasonable legal notices or author attributions in that material or in the Appropriate Legal Notices displayed by works containing it; or
c) Prohibiting misrepresentation of the origin of that material, or requiring that modified versions of such material be marked in reasonable ways as different from the original version; or
d) Limiting the use for publicity purposes of names of licensors or authors of the material; or
e) Declining to grant rights under trademark law for use of some trade names, trademarks, or service marks; or
f) Requiring indemnification of licensors and authors of that material by anyone who conveys the material (or modified versions of it) with contractual assumptions of liability to the recipient, for any liability that these contractual assumptions directly impose on those licensors and authors.
All other non-permissive additional terms are considered “further restrictions” within
the meaning of section 10. If the Program as you received it, or any part of it, contains a
notice stating that it is governed by this License along with a term that is a further
restriction, you may remove that term. If a license document contains a further
restriction but permits relicensing or conveying under this License, you may add to a
covered work material governed by the terms of that license document, provided that
the further restriction does not survive such relicensing or conveying.
If you add terms to a covered work in accord with this section, you must place, in the
relevant source files, a statement of the additional terms that apply to those files, or a
notice indicating where to find the applicable terms.
Additional terms, permissive or non-permissive, may be stated in the form of a
separately written license, or stated as exceptions; the above requirements apply either
way.
8. Termination.
You may not propagate or modify a covered work except as expressly provided under
this License. Any attempt otherwise to propagate or modify it is void, and will
automatically terminate your rights under this License (including any patent licenses
granted under the third paragraph of section 11).
However, if you cease all violation of this License, then your license from a particular
copyright holder is reinstated (a) provisionally, unless and until the copyright holder
explicitly and finally terminates your license, and (b) permanently, if the copyright
10. LICENCIAS
128
holder fails to notify you of the violation by some reasonable means prior to 60 days
after the cessation.
Moreover, your license from a particular copyright holder is reinstated permanently if
the copyright holder notifies you of the violation by some reasonable means, this is the
first time you have received notice of violation of this License (for any work) from that
copyright holder, and you cure the violation prior to 30 days after your receipt of the
notice.
Termination of your rights under this section does not terminate the licenses of parties
who have received copies or rights from you under this License. If your rights have
been terminated and not permanently reinstated, you do not qualify to receive new
licenses for the same material under section 10.
9. Acceptance Not Required for Having Copies.
You are not required to accept this License in order to receive or run a copy of the
Program. Ancillary propagation of a covered work occurring solely as a consequence of
using peer-to-peer transmission to receive a copy likewise does not require acceptance.
However, nothing other than this License grants you permission to propagate or modify
any covered work. These actions infringe copyright if you do not accept this License.
Therefore, by modifying or propagating a covered work, you indicate your acceptance
of this License to do so.
10. Automatic Licensing of Downstream Recipients.
Each time you convey a covered work, the recipient automatically receives a license
from the original licensors, to run, modify and propagate that work, subject to this
License. You are not responsible for enforcing compliance by third parties with this
License.
An “entity transaction” is a transaction transferring control of an organization, or
substantially all assets of one, or subdividing an organization, or merging organizations.
If propagation of a covered work results from an entity transaction, each party to that
transaction who receives a copy of the work also receives whatever licenses to the work
the party's predecessor in interest had or could give under the previous paragraph, plus a
right to possession of the Corresponding Source of the work from the predecessor in
interest, if the predecessor has it or can get it with reasonable efforts.
You may not impose any further restrictions on the exercise of the rights granted or
affirmed under this License. For example, you may not impose a license fee, royalty, or
other charge for exercise of rights granted under this License, and you may not initiate
litigation (including a cross-claim or counterclaim in a lawsuit) alleging that any patent
claim is infringed by making, using, selling, offering for sale, or importing the Program
or any portion of it.
11. Patents.
PROYECTO FIN DE CARRERA
129
A “contributor” is a copyright holder who authorizes use under this License of the
Program or a work on which the Program is based. The work thus licensed is called the
contributor's “contributor version”.
A contributor's “essential patent claims” are all patent claims owned or controlled by the
contributor, whether already acquired or hereafter acquired, that would be infringed by
some manner, permitted by this License, of making, using, or selling its contributor
version, but do not include claims that would be infringed only as a consequence of
further modification of the contributor version. For purposes of this definition, “control”
includes the right to grant patent sublicenses in a manner consistent with the
requirements of this License.
Each contributor grants you a non-exclusive, worldwide, royalty-free patent license
under the contributor's essential patent claims, to make, use, sell, offer for sale, import
and otherwise run, modify and propagate the contents of its contributor version.
In the following three paragraphs, a “patent license” is any express agreement or
commitment, however denominated, not to enforce a patent (such as an express
permission to practice a patent or covenant not to sue for patent infringement). To
“grant” such a patent license to a party means to make such an agreement or
commitment not to enforce a patent against the party.
If you convey a covered work, knowingly relying on a patent license, and the
Corresponding Source of the work is not available for anyone to copy, free of charge
and under the terms of this License, through a publicly available network server or other
readily accessible means, then you must either (1) cause the Corresponding Source to be
so available, or (2) arrange to deprive yourself of the benefit of the patent license for
this particular work, or (3) arrange, in a manner consistent with the requirements of this
License, to extend the patent license to downstream recipients. “Knowingly relying”
means you have actual knowledge that, but for the patent license, your conveying the
covered work in a country, or your recipient's use of the covered work in a country,
would infringe one or more identifiable patents in that country that you have reason to
believe are valid.
If, pursuant to or in connection with a single transaction or arrangement, you convey, or
propagate by procuring conveyance of, a covered work, and grant a patent license to
some of the parties receiving the covered work authorizing them to use, propagate,
modify or convey a specific copy of the covered work, then the patent license you grant
is automatically extended to all recipients of the covered work and works based on it.
A patent license is “discriminatory” if it does not include within the scope of its
coverage, prohibits the exercise of, or is conditioned on the non-exercise of one or more
of the rights that are specifically granted under this License. You may not convey a
covered work if you are a party to an arrangement with a third party that is in the
business of distributing software, under which you make payment to the third party
based on the extent of your activity of conveying the work, and under which the third
party grants, to any of the parties who would receive the covered work from you, a
discriminatory patent license (a) in connection with copies of the covered work
10. LICENCIAS
130
conveyed by you (or copies made from those copies), or (b) primarily for and in
connection with specific products or compilations that contain the covered work, unless
you entered into that arrangement, or that patent license was granted, prior to 28 March
2007.
Nothing in this License shall be construed as excluding or limiting any implied license
or other defenses to infringement that may otherwise be available to you under
applicable patent law.
12. No Surrender of Others' Freedom.
If conditions are imposed on you (whether by court order, agreement or otherwise) that
contradict the conditions of this License, they do not excuse you from the conditions of
this License. If you cannot convey a covered work so as to satisfy simultaneously your
obligations under this License and any other pertinent obligations, then as a
consequence you may not convey it at all. For example, if you agree to terms that
obligate you to collect a royalty for further conveying from those to whom you convey
the Program, the only way you could satisfy both those terms and this License would be
to refrain entirely from conveying the Program.
13. Use with the GNU Affero General Public License.
Notwithstanding any other provision of this License, you have permission to link or
combine any covered work with a work licensed under version 3 of the GNU Affero
General Public License into a single combined work, and to convey the resulting work.
The terms of this License will continue to apply to the part which is the covered work,
but the special requirements of the GNU Affero General Public License, section 13,
concerning interaction through a network will apply to the combination as such.
14. Revised Versions of this License.
The Free Software Foundation may publish revised and/or new versions of the GNU
General Public License from time to time. Such new versions will be similar in spirit to
the present version, but may differ in detail to address new problems or concerns.
Each version is given a distinguishing version number. If the Program specifies that a
certain numbered version of the GNU General Public License “or any later version”
applies to it, you have the option of following the terms and conditions either of that
numbered version or of any later version published by the Free Software Foundation. If
the Program does not specify a version number of the GNU General Public License, you
may choose any version ever published by the Free Software Foundation.
If the Program specifies that a proxy can decide which future versions of the GNU
General Public License can be used, that proxy's public statement of acceptance of a
version permanently authorizes you to choose that version for the Program.
PROYECTO FIN DE CARRERA
131
Later license versions may give you additional or different permissions. However, no
additional obligations are imposed on any author or copyright holder as a result of your
choosing to follow a later version.
15. Disclaimer of Warranty.
THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT
PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN
WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE
THE PROGRAM “AS IS” WITHOUT WARRANTY OF ANY KIND, EITHER
EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF
THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE,
YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR
CORRECTION.
16. Limitation of Liability.
IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO
MODIFIES AND/OR CONVEYS THE PROGRAM AS PERMITTED ABOVE, BE
LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL,
INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE
OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO
LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES
SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM
TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR
OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
DAMAGES.
17. Interpretation of Sections 15 and 16.
If the disclaimer of warranty and limitation of liability provided above cannot be given
local legal effect according to their terms, reviewing courts shall apply local law that
most closely approximates an absolute waiver of all civil liability in connection with the
Program, unless a warranty or assumption of liability accompanies a copy of the
Program in return for a fee.
END OF TERMS AND CONDITIONS
10. LICENCIAS
132
10.4 REVPROXY
Dj-Revproxy ha sido integrado en el proyecto y está sujeto a una licencia
diferente a ésta Aun así, es compatible con el proyecto ya que está licenciado bajo la
licencia MIT.
The MIT License (MIT)
Copyright (c) 2010 Benoit Chesneau <[email protected]>
Permission is hereby granted, free of charge, to any person
obtaining a copy of this software and associated documentation
files (the "Software"), to deal in the Software without
restriction, including without limitation the rights to use,
copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following
conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
OTHER DEALINGS IN THE SOFTWARE.
PROYECTO FIN DE CARRERA
133
11. GLOSARIO
Abstracta (Clase): En ingeniería de software, un tipo abstracto es un tipo en un
sistema de tipo nominativo que es declarado por el programador, y que tiene la
propiedad de no contener miembros que no sean miembros de algún subtipo
declarado. Según el lenguaje de programación orientada a objetos, los tipos abstractos
se implementan bajo nombres como clases base abstractas, interfaces, traits (en
inglés, rasgos), mixins, flavors (en inglés, sabores) o roles.
Android: Es un sistema operativo basado en Linux diseñado originalmente para
dispositivos móviles, tales como teléfonos inteligentes, pero que posteriormente se
expandió su desarrollo para soportar otros dispositivos tales como tablets,
reproductores MP3, netbooks, PCs e incluso televisores.
ANSI: El Instituto Nacional Estadounidense de Estándares (ANSI, por sus siglas en
inglés: American National Standards Institute) es una organización sin ánimo de lucro
que supervisa el desarrollo de estándares para productos, servicios, procesos y
sistemas en los Estados Unidos. ANSI es miembro de la Organización Internacional
para la Estandarización (ISO) y de la Comisión Electrotécnica Internacional
(International Electrotechnical Commission, IEC). La organización también coordina
estándares del país estadounidense con estándares internacionales.
Apache: El servidor HTTP Apache es un servidor web HTTP de código abierto para
plataformas Unix (BSD, GNU/Linux, etc.), Microsoft Windows, Macintosh y otras, que
implementa el protocolo HTTP/1.12 y la noción de sitio virtual.
API: Una interfaz de programación de aplicaciones o API (del inglés Application
Programming Interface) es el conjunto de funciones y procedimientos (o métodos, en
la programación orientada a objetos) que ofrece cierta biblioteca para ser utilizado por
otro software como una capa de abstracción. Son usadas generalmente en las
bibliotecas (también denominadas comúnmente "librerías").
Atributo: En computación, un atributo es una especificación que define una propiedad
de un Objeto, elemento o archivo. También puede referirse o establecer el valor
específico para una instancia determinada de los mismos. Sin embargo, actualmente,
el término atributo puede y con frecuencia se considera como si fuera una propiedad
dependiendo de la tecnología que se use. Para mayor claridad, los atributos deben ser
considerados más correctamente como metadatos. Un atributo es con frecuencia y en
general una característica de una propiedad.
Backend: En diseño de software el front-end es la parte del software que interactúa
con el o los usuarios y el back-end es la parte que procesa la entrada desde el front-
end. La separación del sistema en "front ends" y "back ends" es un tipo de abstracción
que ayuda a mantener las diferentes partes del sistema separadas.
11. GLOSARIO
134
Binding: En el campo de la programación, un binding es una adaptación de una
biblioteca para ser usada en un lenguaje de programación distinto de aquél en el que
ha sido escrita.
Bool: El tipo de dato lógico o booleano es en computación aquel que puede
representar valores de lógica binaria, esto es 2 valores, valores que normalmente
representan falso o verdadero. Se utiliza normalmente en la programación, estadística,
electrónica, matemáticas (Álgebra booleana), etc...
Caché: Se llama caché web a la caché que almacena documentos web (es decir,
páginas, imágenes, etcétera) para reducir el ancho de banda consumido, la carga de
los servidores y el retardo en la descarga. Un caché web almacena copias de los
documentos que pasan por él, de forma que subsiguientes peticiones pueden ser
respondidas por el propio caché, si se cumplen ciertas condiciones.
Cherokee: Es un servidor web multiplataforma.2 Su objetivo es ser rápido y
completamente funcional, sin dejar de ser liviano comparado con otros servidores
web.3 Está escrito completamente en C. Puede usarse como un sistema embebido y
soporta complementos para aumentar sus funcionalidades. Es software libre,
disponible bajo la Licencia Pública General de GNU.
Clase: En informática, se llama clase a la declaración o abstracción de un objeto
cuando se programa según el paradigma de orientación a objetos.
CouchDB: Es una base de datos documental sin schema, consultable al estilo
MapReduce, accesible por REST y con una funcionalidad de replicación integrada. Es
denominada NoSQL entre muchas otras.
CORBA: En computación, CORBA (Common Object Request Broker Architecture —
arquitectura común de intermediarios en peticiones a objetos); es un estándar que
establece una plataforma de desarrollo de sistemas distribuidos facilitando la
invocación de métodos remotos bajo un paradigma orientado a objetos.
CSRF: (del inglés Cross-site request forgery o falsificación de petición en sitios
cruzados) es un tipo de exploit malicioso de un sitio web en el que comandos no
autorizados son transmitidos por un usuario en el cual el sitio web confía. Esta
vulnerabilidad es conocida también por otros nombres como XSRF, enlace hostil,
ataque de un click, cabalgamiento de sesión, y ataque automático.
CSS: El nombre hojas de estilo en cascada viene del inglés Cascading Style Sheets,
del que toma sus siglas. CSS es un lenguaje usado para definir la presentación de un
documento estructurado escrito en HTML o XML (y por extensión en XHTML). El W3C
(World Wide Web Consortium) es el encargado de formular la especificación de las
hojas de estilo que servirán de estándar para los agentes de usuario o navegadores.
PROYECTO FIN DE CARRERA
135
DOT: Es un lenguaje para la creación de grafos. Es una manera simple de describir
gráficos que los seres humanos y los programas de ordenador pueden utilizar.
Normalmente terminan con la extensión. Gv (o. Punto) de extensión.
DRY: El principio No te repitas (en inglés Don't Repeat Yourself o DRY, también
conocido como Una vez y sólo una) es una filosofía de definición de procesos que
promueve la reducción de la duplicación especialmente en computación. Según este
principio toda pieza de información nunca debería ser duplicada debido a que la
duplicación incrementa la dificultad en los cambios y evolución posterior, puede
perjudicar la claridad y crear un espacio para posibles inconsistencias.
Framework: Desde el punto de vista del desarrollo de software, un framework es una
estructura de soporte definida, en la cual otro proyecto de software puede ser
organizado y desarrollado. Típicamente, puede incluir soporte de programas,
bibliotecas y un lenguaje interpretado entre otros programas para ayudar a desarrollar
y unir los diferentes componentes de un proyecto.
Float: El tipo de dato real define un conjunto de números que pueden ser
representados con la notación de coma flotante. Al igual que los números enteros, el
tipo real está limitado superior e inferiormente según la cantidad de memoria que haya
disponible para almacenarlo. Otro elemento importante a tener en cuenta en este tipo
de datos es la precisión con que pueden representar número con decimales (cuantos
decimales se pueden representar), esta característica también está directamente
relacionada con la cantidad de memoria disponible para almacenar un valor real.
Función: En computación, una subrutina o subprograma (también llamada
procedimiento, función o rutina), como idea general, se presenta como un
subalgoritmo que forma parte del algoritmo principal, el cual permite resolver una tarea
específica. Algunos lenguajes de programación, como Visual Basic .NET o Fortran,
utilizan el nombre función para referirse a subrutinas que devuelven un valor. Una
subrutina al ser llamada dentro de un programa hace que el código principal se
detenga y se dirija a ejecutar el código de la subrutina, en cambio cuando se llama a
una macro, el compilador toma el código de la macro y lo implanta donde fue llamado,
aumentando así el código fuente y por consiguiente el objeto.
FTP: FTP (sigla en inglés de File Transfer Protocol - Protocolo de Transferencia de
Archivos) en informática, es un protocolo de red para la transferencia de archivos entre
sistemas conectados a una red TCP (Transmission Control Protocol), basado en la
arquitectura cliente-servidor. Desde un equipo cliente se puede conectar a un servidor
para descargar archivos desde él o para enviarle archivos, independientemente del
sistema operativo utilizado en cada equipo.
Geany: Es un editor de texto ligero basado en Scintilla con características básicas de
entorno de desarrollo integrado (IDE). Está disponible para distintos sistemas
11. GLOSARIO
136
operativos, como GNU/Linux, Mac OS X, BSD, Solaris y Microsoft Windows. Es
distribuido como software libre bajo la Licencia Pública General de GNU.
GNU: El proyecto GNU fue iniciado por Richard Stallman con el objetivo de crear un
sistema operativo completamente libre: el sistema GNU. El 27 de septiembre de 1983
se anunció públicamente el proyecto por primera vez en el grupo de noticias net.unix-
wizards. Al anuncio original, siguieron otros ensayos escritos por Richard Stallman
como el "Manifiesto GNU", que establecieron sus motivaciones para realizar el
proyecto GNU, entre las que destaca "volver al espíritu de cooperación que prevaleció
en los tiempos iniciales de la comunidad de usuarios de computadoras".
GNU/Linux: Es uno de los términos empleados para referirse a la combinación del
núcleo o kernel libre similar a Unix denominado Linux, que es usado con herramientas
de sistema GNU. Su desarrollo es uno de los ejemplos más prominentes de software
libre; todo su código fuente puede ser utilizado, modificado y redistribuido libremente
por cualquiera bajo los términos de la GPL (Licencia Pública General de GNU, en
inglés: Generale Public License) y otra serie de licencias libres.
Hash: Se refiere a una función o método para generar claves o llaves que representen
de manera casi unívoca a un documento, registro, archivo, etc., resumir o identificar un
dato a través de la probabilidad, utilizando una función hash o algoritmo hash. Un hash
es el resultado de dicha función o algoritmo.
HTML: Son las siglas de HyperText Markup Language (Lenguaje de Marcado de
Hipertexto), es el lenguaje de marcado predominante para la elaboración de páginas
web. Es usado para describir la estructura y el contenido en forma de texto, así como
para complementar el texto con objetos tales como imágenes. HTML se escribe en
forma de «etiquetas», rodeadas por corchetes angulares (<,>). HTML también puede
describir, hasta un cierto punto, la apariencia de un documento, y puede incluir un
script (por ejemplo Javascript), el cual puede afectar el comportamiento de
navegadores web y otros procesadores de HTML.
HTTP: Hypertext Transfer Protocol o HTTP (en español protocolo de transferencia de
hipertexto) es el protocolo usado en cada transacción de la World Wide Web. HTTP
fue desarrollado por el World Wide Web Consortium y la Internet Engineering Task
Force, colaboración que culminó en 1999 con la publicación de una serie de RFC, el
más importante de ellos es el RFC 2616 que especifica la versión 1.1. HTTP define la
sintaxis y la semántica que utilizan los elementos de software de la arquitectura web
(clientes, servidores, proxies) para comunicarse. Es un protocolo orientado a
transacciones y sigue el esquema petición-respuesta entre un cliente y un servido.
IDE: Un entorno de desarrollo integrado (en inglés integrated development
environment) es un programa informático compuesto por un conjunto de herramientas
de programación. Puede dedicarse en exclusiva a un sólo lenguaje de programación o
bien, poder utilizarse para varios. Un IDE es un entorno de programación que ha sido
PROYECTO FIN DE CARRERA
137
empaquetado como un programa de aplicación, es decir, consiste en un editor de
código, un compilador, un depurador y un constructor de interfaz gráfica (GUI).
Int (Integer): Un tipo de dato entero en computación es un tipo de dato que puede
representar un subconjunto finito de los números enteros. El número mayor que puede
representar depende del tamaño del espacio usado por el dato y la posibilidad (o no)
de representar números negativos. Los tipos de dato entero disponibles y su tamaño
dependen del lenguaje de programación usado así como la arquitectura en cuestión.
Interfaz: La interfaz de usuario es el medio con que el usuario puede comunicarse con
una máquina, un equipo o una computadora, y comprende todos los puntos de
contacto entre el usuario y el equipo, normalmente suelen ser fáciles de entender y
fáciles de accionar.
JavaScript: Es un lenguaje de programación interpretado, dialecto del estándar
ECMAScript. Se define como orientado a objetos, basado en prototipos, imperativo,
débilmente tipado y dinámico. Se utiliza principalmente en su forma del lado del cliente
(client-side), implementado como parte de un navegador web permitiendo mejoras en
la interfaz de usuario y páginas web dinámicas, aunque existe una forma de JavaScript
del lado del servidor (Server-side JavaScript o SSJS).
jQuery: Es una biblioteca o framework de JavaScript, creada inicialmente por John
Resig, que permite simplificar la manera de interactuar con los documentos HTML,
manipular el árbol DOM, manejar eventos, desarrollar animaciones y agregar
interacción con la técnica AJAX a páginas web.
LaTeX: (escrito LaTeX en texto plano) es un sistema de composición de
textos, orientado especialmente a la creación de libros, documentos científicos y
técnicos que contengan fórmulas matemáticas. LaTeX está formado por un gran
conjunto de macros de TeX, escrito por Leslie Lamport en 1984, con la intención de
facilitar el uso del lenguaje de composición tipográfica. Creado por Donald Knuth. Es
muy utilizado para la composición de artículos académicos, tesis y libros técnicos,
dado que la calidad tipográfica de los documentos realizados con LaTeX es
comparable a la de una editorial científica de primera línea.
Link: Un hipervínculo (también llamado enlace, vínculo, o hiperenlace) es un elemento
de un documento electrónico que hace referencia a otro recurso, por ejemplo, otro
documento o un punto específico del mismo o de otro documento. Combinado con una
red de datos y un protocolo de acceso, un hipervinculo permite acceder al recurso
referenciado en diferentes formas, como visitarlo con un agente de navegación,
mostrarlo como parte del documento referenciador o guardarlo localmente. Los
hipervínculos son parte fundamental de la arquitectura de la World Wide Web, pero el
concepto no se limita al HTML o a la Web. Casi cualquier medio electrónico puede
emplear alguna forma de hiperenlace.
11. GLOSARIO
138
Linux: GNU/Linux es uno de los términos empleados para referirse a la combinación
del núcleo o kernel libre similar a Unix denominado Linux, que es usado con
herramientas de sistema GNU. Su desarrollo es uno de los ejemplos más prominentes
de software libre; todo su código fuente puede ser utilizado, modificado y redistribuido
libremente por cualquiera bajo los términos de la GPL.
Login/logout: En el ámbito de seguridad informática, login o logon (en español
ingresar o entrar) es el proceso mediante el cual se controla el acceso individual a un
sistema informático mediante la identificación del usuario utilizando credenciales
provistas por el usuario. Un usuario se puede log in a un sistema para obtener acceso
y se puede log out o log off (en español salir o desconectar) cuando no se precisa
mantener el acceso. Log out consiste en cerrar el acceso personal a un sistema
informático, al cual anteriormente se había realizado el login.
Memory Leak: Una fuga de memoria (más conocido por el término inglés memory
leak) es un error de software que ocurre cuando un bloque de memoria reservada no
es liberada en un programa de computación. Comúnmente ocurre porque se pierden
todas las referencias a esa área de memoria antes de haberse liberado. Dependiendo
de la cantidad de memoria perdida y el tiempo que el programa siga en ejecución, este
problema puede llevar al agotamiento de la memoria disponible en la computadora.
Método: En la programación orientada a objetos, un método es una subrutina
asociada exclusivamente a una clase (llamados métodos de clase o métodos
estáticos) o a un objeto (llamados métodos de instancia). Análogamente a los
procedimientos en los lenguajes imperativos, un método consiste generalmente de una
serie de sentencias para llevar a cabo una acción, un juego de parámetros de entrada
que regularán dicha acción y, posiblemente, un valor de salida (o valor de retorno) de
algún tipo.
Middleware: Middleware es un software que asiste a una aplicación para interactuar o
comunicarse con otras aplicaciones, software, redes, hardware y/o sistemas
operativos. Éste simplifica el trabajo de los programadores en la compleja tarea de
generar las conexiones que son necesarias en los sistemas distribuidos. De esta forma
se provee una solución que mejora la calidad de servicio, seguridad, envío de
mensajes, directorio de servicio, etc.
Módulo: Para facilitar el mantenimiento y la lectura los programas demasiado largos
pueden dividirse en módulos, agrupando elementos relacionados. Los módulos son
entidades que permiten una organización y división lógica de nuestro código.
MVC: Modelo Vista Controlador (MVC) es un patrón de arquitectura de software que
separa los datos de una aplicación, la interfaz de usuario, y la lógica de control en tres
componentes distintos. El patrón de llamada y retorno MVC (según CMU), se ve
frecuentemente en aplicaciones web, donde la vista es la página HTML y el código que
provee de datos dinámicos a la página. El modelo es el Sistema de Gestión de Base
PROYECTO FIN DE CARRERA
139
de Datos y la Lógica de negocio, y el controlador es el responsable de recibir los
eventos de entrada desde la vista.
Nginx: Es un servidor web/proxy inverso ligero de alto rendimiento y un proxy para
protocolos de correo electrónico (IMAP/POP3). Es software libre y de código abierto,
licenciado bajo la Licencia BSD simplificada. Es multiplataforma, por lo que corre en
sistemas tipo Unix (GNU/Linux, BSD, Solaris, Mac OS X, etc.) y Windows. El sistema
es usado por una larga lista de sitios web conocidos, como: WordPress, Hulu, GitHub,
Ohloh, SourceForge y TorrentReactor.
OAuth: (Open Authorization) es un protocolo abierto, propuesto por Blaine Cook y
Chris Messina, que permite autorización segura de un API de modo estándar y simple
para aplicaciones de escritorio, móviles, y web. Para desarrolladores de consumidores,
OAuth es un método de interactuar con y publicar datos protegidos. Para
desarrolladores de proveedores de servicio, OAuth proporciona a los usuarios un
acceso a sus datos al mismo tiempo que protege las credenciales de su cuenta. En
otras palabras, OAuth permite a un usuario del sitio A compartir su información en el
sitio A (proveedor de servicio) con el sitio B (llamado consumidor) sin compartir toda su
identidad.
Objeto: En el paradigma de programación orientada a objetos (POO, o bien OOP en
inglés), un objeto se define como la unidad que en tiempo de ejecución realiza las
tareas de un programa. También a un nivel más básico se define como la instancia de
una clase. Estos objetos interactúan unos con otros, en contraposición a la visión
tradicional en la cual un programa es una colección de subrutinas (funciones o
procedimientos), o simplemente una lista de instrucciones para el computador. Cada
objeto es capaz de recibir mensajes, procesar datos y enviar mensajes a otros objetos
de manera similar a un servicio. En el mundo de la programación orientada a objetos
(POO), un objeto es el resultado de la instanciación de una clase.
OWL: Es el acrónimo del inglés Ontology Web Language, un lenguaje de marcado
para publicar y compartir datos usando ontologías en la WWW. OWL tiene como
objetivo facilitar un modelo de marcado construido sobre RDF y codificado en XML.
Tiene como antecedente DAML+OIL, en los cuales se inspiraron los creadores de
OWL para crear el lenguaje. Junto al entorno RDF y otros componentes, estas
herramientas hacen posible el proyecto de web semántica.
Parser: Un analizador sintáctico (en inglés parser). El análisis sintáctico convierte el
texto de entrada en otras estructuras (comúnmente árboles), que son más útiles para
el posterior análisis y capturan la jerarquía implícita de la entrada. Un analizador léxico
crea tokens de una secuencia de caracteres de entrada y son estos tokens los que son
procesados por el analizador sintáctico para construir la estructura de datos, por
ejemplo un árbol de análisis o árboles de sintaxis abstracta.
11. GLOSARIO
140
Plug-in: Un plug-in o complemento en castellano, es un pequeño programa que puede
anexarse a otro, habitualmente de mayor tamaño, para aumentar sus funcionalidades
(generalmente sin afectar otras funciones ni afectar la aplicación principal).
PNG: (sigla en inglés de portable network graphics) es un formato gráfico basado en
un algoritmo de compresión sin pérdida para bitmaps no sujeto a patentes. Este
formato fue desarrollado en buena parte para solventar las deficiencias del formato
GIF y permite almacenar imágenes con una mayor profundidad de contraste y otros
importantes datos.
Query: En términos informáticos se refiere a una consulta, normalmente sobre una
base de datos mediante lenguaje SQL.
RDF: El Marco de Descripción de Recursos (del inglés Resource Description
Framework, RDF) es un framework para metadatos en la World Wide Web (WWW),
desarrollado por el World Wide Web Consortium (W3C).
Es un lenguaje de objetivo general para representar la información en la web (un
metadato data model). Es una descripción conceptual.
RDFa: Es un conjunto de extensiones de XHTML propuestas por W3C para introducir
semántica en los documentos. RDFa aprovecha atributos de los elementos meta y link
de XHTML y los generaliza de forma que puedan ser utilizados en otros elementos.
Además se ha definido una correspondencia simple que permite extraer tripletes RDF.
Regex: Proviene de regular expression, o expresión regular.
Sandbox: En el contexto de desarrollo de software o desarrollo web, es un entorno de
pruebas que aísla los cambios en el código, fruto de la experimentación, del el propio
entorno de producción o entorno de edición (en caso de las wikis)
Script: Un script (cuya traducción literal es 'guion') o archivo de órdenes o archivo de
procesamiento por lotes es un programa usualmente simple, que por lo regular se
almacena en un archivo de texto plano. Los script son casi siempre interpretados, pero
no todo programa interpretado es considerado un script. El uso habitual de los scripts
es realizar diversas tareas como combinar componentes, interactuar con el sistema
operativo o con el usuario. Por este uso es frecuente que los shells sean a la vez
intérpretes de este tipo de programas.
SCV: Revision Control System o RCS es una implementación en software del control
de versiones que automatiza las tareas de guardar, recuperar, registrar, identificar y
mezclar versiones de archivos. RCS es útil para archivos que son modificados
frecuentemente, por ejemplo programas informáticos, documentación, gráficos de
procedimientos, monografías y cartas. RCS también puede ser utilizado para manejar
archivos binarios, pero con eficacia y eficiencia reducidas. Las distintas versiones son
archivadas mediante la ayuda de la herramienta diff.
PROYECTO FIN DE CARRERA
141
Serializer: La serialización consiste en la transformación de un tipo de datos o formato
a otro diferente. Por ejemplo de XML a JSON. El serializer o serializador es el
encargado de efectuar esta transformación.
SMS: El servicio de mensajes cortos o SMS (Short Message Service) es un servicio
disponible en los teléfonos móviles que permite el envío de mensajes cortos (también
conocidos como mensajes de texto, o más coloquialmente, textos) entre teléfonos
móviles, teléfonos fijos y otros dispositivos de mano. SMS fue diseñado
originariamente como parte del estándar de telefonía móvil digital GSM, pero en la
actualidad está disponible en una amplia variedad de redes, incluyendo las redes 3G.
SSH: (Secure SHell, en español: intérprete de órdenes segura) es el nombre de un
protocolo y del programa que lo implementa, y sirve para acceder a máquinas remotas
a través de una red. Permite manejar por completo la computadora mediante un
intérprete de comandos, y también puede redirigir el tráfico de X para poder ejecutar
programas gráficos si tenemos un Servidor X (en sistemas Unix y Windows) corriendo.
Además de la conexión a otros dispositivos, SSH nos permite copiar datos de forma
segura (tanto ficheros sueltos como simular sesiones FTP cifradas), gestionar claves
RSA para no escribir claves al conectar a los dispositivos y pasar los datos de
cualquier otra aplicación por un canal seguro tunelizado mediante SSH.
String: En matemáticas o en programación, una cadena de caracteres, palabra, ristra
de caracteres o frase (string en inglés) es una secuencia ordenada de longitud
arbitraria (aunque finita) de elementos que pertenecen a un cierto alfabeto. En general,
una cadena de caracteres es una sucesión de caracteres (letras, números u otros
signos o símbolos).
SQL: El lenguaje de consulta estructurado o SQL (por sus siglas en inglés structured
query language) es un lenguaje declarativo de acceso a bases de datos relacionales
que permite especificar diversos tipos de operaciones en éstas. Una de sus
características es el manejo del álgebra y el cálculo relacional permitiendo efectuar
consultas con el fin de recuperar -de una forma sencilla- información de interés de una
base de datos, así como también hacer cambios sobre ella.
SSL: Secure Sockets Layer (SSL; protocolo de capa de conexión segura) y su sucesor
Transport Layer Security (TLS; seguridad de la capa de transporte) son protocolos
criptográficos que proporcionan comunicaciones seguras por una red, comúnmente
Internet.
SVN: Subversion es un sistema de control de versiones diseñado específicamente
para reemplazar al popular CVS. Es software libre bajo una licencia de tipo
Apache/BSD y se le conoce también como svn por ser el nombre de la herramienta
utilizada en la línea de órdenes.
11. GLOSARIO
142
SVG: Los Gráficos Vectoriales Escalables (del inglés Scalable Vector Graphics) o SVG
es una especificación para describir gráficos vectoriales bidimensionales, tanto
estáticos como animados (estos últimos con ayuda de SMIL), en formato XML.
TCP/IP: La familia de protocolos de Internet es un conjunto de protocolos de red en los
que se basa Internet y que permiten la transmisión de datos entre computadoras. En
ocasiones se le denomina conjunto de protocolos TCP/IP, en referencia a los dos
protocolos más importantes que la componen: Protocolo de Control de Transmisión
(TCP) y Protocolo de Internet (IP), que fueron dos de los primeros en definirse, y que
son los más utilizados de la familia.
Twitter: Es una red social basada en el microblogging. La red permite mandar
mensajes de texto plano de bajo tamaño con un máximo de 140 caracteres, llamados
tweets, que se muestran en la página principal del usuario. Los usuarios pueden
suscribirse a los tweets de otros usuarios.
Unicode: El Estándar Unicode es un estándar de codificación de caracteres diseñado
para facilitar el tratamiento informático, transmisión y visualización de textos de
múltiples lenguajes y disciplinas técnicas además de textos clásicos de lenguas
muertas. El término Unicode proviene de los tres objetivos perseguidos: universalidad,
uniformidad y unicidad. Unicode especifica un nombre e identificador numérico único
para cada caracter o símbolo, el code point o punto de código, además de otras
informaciones necesarias para su uso correcto: direccionalidad, capitalización y otros
atributos. Unicode trata los caracteres alfabéticos, ideográficos y símbolos de forma
equivalente, lo que significa que se pueden mezclar en un mismo texto sin la
introducción de marcas o caracteres de control.
URL: Un localizador uniforme de recursos o más comúnmente denominado URL (sigla
en inglés de uniform resource locator), es una secuencia de caracteres, de acuerdo a
un formato modélico y estándar, que se usa para nombrar recursos (como por ejemplo
documentos textuales, imágenes, vídeos etc.) en Internet para su localización o
identificación.
URI: Un Uniform Resource Identifier o URI (en español "identificador uniforme de
recurso") es una cadena de caracteres corta que identifica inequívocamente un
recurso (servicio, página, documento, dirección de correo electrónico, enciclopedia,
etc.). Normalmente estos recursos son accesibles en una red o sistema. Los URI
pueden ser localizadores uniformes de recursos, Uniform Resource Name, o ambos.
UTF: Es un formato de codificación Unicode. Existen varios tipos como UTF-8 o UTF-
16 entre otros.
Variable: En programación, las variables son espacios reservados en la memoria que,
como su nombre indica, pueden cambiar de contenido a lo largo de la ejecución de un
programa. Una variable corresponde a un área reservada en la memoria principal del
ordenador pudiendo ser de longitud variable o fija
PROYECTO FIN DE CARRERA
143
Wizard: Normalmente se refiere a la palabra en castellano “Asistente” ayudando así
en los pasos para llegar ha ejecutar una acción. El asistente o wizard guía al usuario
con consejos, pasos automatizados o explicaciones.
XHTML: XHTML, acrónimo en inglés de eXtensible Hypertext Markup Language
(lenguaje extensible de marcado de hipertexto), es el lenguaje de marcado pensado
para sustituir a HTML como estándar para las páginas web. En su versión 1.0, XHTML
es solamente la versión XML de HTML, por lo que tiene, básicamente, las mismas
funcionalidades, pero cumple las especificaciones, más estrictas, de XML. Su objetivo
es avanzar en el proyecto del World Wide Web Consortium de lograr una web
semántica, donde la información, y la forma de presentarla estén claramente
separadas. La versión 1.1 es similar, pero parte a la especificación en módulos.
XML: Son las siglas en inglés de eXtensible Markup Language ('lenguaje de marcas
extensible'), es un metalenguaje extensible de etiquetas desarrollado por el World
Wide Web Consortium (W3C). Es una simplificación y adaptación del SGML y permite
definir la gramática de lenguajes específicos (de la misma manera que HTML es a su
vez un lenguaje definido por SGML). Por lo tanto XML no es realmente un lenguaje en
particular, sino una manera de definir lenguajes para diferentes necesidades.
XSL: Siglas de Extensible Stylesheet Language, expresión inglesa traducible como
"lenguaje extensible de hojas de estilo". Es una familia de lenguajes basados en el
estándar XML que permite describir cómo la información contenida en un documento
XML cualquiera debe ser transformada o formateada para su presentación en un
medio.
XSLT: XSLT o Transformaciones XSL es un estándar de la organización W3C que
presenta una forma de transformar documentos XML en otros e incluso a formatos que
no son XML. Las hojas de estilo XSLT - aunque el término de hojas de estilo no se
aplica sobre la función directa del XSLT - realizan la transformación del documento
utilizando una o varias reglas de plantilla.
W3C: El World Wide Web Consortium, abreviado W3C, es un consorcio internacional
que produce recomendaciones para la World Wide Web. Está dirigida por Tim
Berners-Lee, el creador original de URL (Uniform Resource Locator, Localizador
Uniforme de Recursos), HTTP (HyperText Transfer Protocol, Protocolo de
Transferencia de HiperTexto) y HTML (Lenguaje de Marcado de HiperTexto) que son
las principales tecnologías sobre las que se basa la Web.
PROYECTO FIN DE CARRERA
145
12. BIBLIOGRAFÍA
12.1 PROXYS (VER 3.1)
http://es.wikipedia.org/wiki/Proxy
http://en.wikipedia.org/wiki/Proxy
http://en.wikipedia.org/wiki/Open_proxy
http://en.wikipedia.org/wiki/Reverse_proxy
http://httpd.apache.org/docs/2.0/mod/mod_proxy.html#forwardreverse
http://www.visolve.com/squid/whitepapers/reverseproxy.php
12.2 WEB SEMÁNTICA (VER 3.2)
http://en.wikipedia.org/wiki/Semantic_Web
http://www.w3.org/2001/sw/SW-FAQ
http://www.w3.org/2001/sw/
http://www.w3c.es/divulgacion/guiasbreves/websemantica
http://es.wikipedia.org/wiki/Web_sem%C3%A1ntica
http://www.maestrosdelweb.com/editorial/web-semantica-y-sus-principales-
caracteristicas/
http://web30websemantica.comuf.com/websemantica.htm
http://semanticweb.org/wiki/Main_Page
12.3 ONTOLOGÍAS (VER 3.3)
http://es.wikipedia.org/wiki/Ontolog%C3%ADa_%28inform%C3%A1tica%29
http://www.w3c.es/Traducciones/es/SW/2005/owlfaq
http://en.wikipedia.org/wiki/Ontology_%28information_science%29
http://www-ksl.stanford.edu/kst/what-is-an-ontology.html
http://es.wikipedia.org/wiki/OWL
http://www.w3.org/TR/owl-features
http://www.dcc.uchile.cl/~ekrsulov/slides/titulo/slide3-0.html
12.4 SPARQL (VER 3.4)
http://www.w3.org/TR/rdf-sparql-query/
http://es.wikipedia.org/wiki/SPARQL
http://en.wikipedia.org/wiki/SPARQL
http://www.cambridgesemantics.com/2008/09/sparql-by-example/#%281%29
12. BIBLIOGRAFÍA
146
12.5 LINKED DATA (VER 3.5)
http://linkeddata.org/
http://es.wikipedia.org/wiki/Datos_vinculados
http://en.wikipedia.org/wiki/Linked_Data
http://www.w3c.es/divulgacion/guiasbreves/LinkedData
http://www.w3.org/DesignIssues/LinkedData.html
http://www.dreig.eu/caparazon/2009/07/12/web-semantica-linked-data-web-ultimos-
conceptos-tendencias-y-aplicaciones/
12.6 EXPRESIONES REGULARES (VER 3.6)
http://www.tutorialspoint.com/python/python_reg_expressions.htm
http://en.wikipedia.org/wiki/Regular_expression
http://es.wikipedia.org/wiki/Expresi%C3%B3n_regular
http://docs.python.org/library/re.html
http://docs.python.org/howto/regex.html
http://diveintopython.org/regular_expressions/index.html
12.7 GRDDL (VER 3.7)
http://www.w3.org/2004/01/rdxh/spec
http://www.w3.org/TR/grddl-primer/
http://es.wikipedia.org/wiki/GRDDL
http://en.wikipedia.org/wiki/GRDDL
http://www4.wiwiss.fu-berlin.de/bizer/rdfapi/tutorial/grddl_parser.htm
http://www.w3.org/TR/2007/REC-grddl-20070911/
12.8 PYTHON (VER 5.2.1)
http://www.python.org/
http://es.wikipedia.org/wiki/Python
http://www.python.org/doc/
http://en.wikipedia.org/wiki/Python_%28programming_language%29
12.9 DJANGO (VER 5.2.2)
https://www.djangoproject.com/
https://docs.djangoproject.com/en/1.3/
http://es.wikipedia.org/wiki/Django
http://django.es/
http://www.flickr.com/photos/jcroft/432038560
http://laurii.info/2010/12/django-development-2-application-development/
PROYECTO FIN DE CARRERA
147
12.10 DJANGO REVPROXY (VER 5.2.3)
https://github.com/benoitc/dj-revproxy
12.11 REDLAND (VER 5.2.4)
http://librdf.org/
http://librdf.org/raptor/
http://librdf.org/rasqal/
http://librdf.org/bindings/
12.12 GIT (VER 5.2.5)
http://git-scm.com/
http://es.wikipedia.org/wiki/Git
http://en.wikipedia.org/wiki/Git_%28software%29
https://github.com/
http://gitorious.org/
http://book.git-scm.com/
http://progit.org/book/
12.13 RESTKIT (VER 5.3.1)
https://github.com/benoitc/restkit
http://benoitc.github.com/restkit/
http://es.wikipedia.org/wiki/Seguridad_en_hilos
12.14 LXML (VER 5.3.2)
http://lxml.de/
12.15 PYGMENTS (VER 5.3.3)
http://pygments.org/
12.16 PYTHON GRAPH (VER 5.3.4)
http://code.google.com/p/python-graph/
12. BIBLIOGRAFÍA
148
http://www.graphviz.org/
http://en.wikipedia.org/wiki/Graphviz
http://www.graphviz.org/content/cluster
12.17 BEAUTIFUL SOUP (VER 5.3.5)
http://www.crummy.com/software/BeautifulSoup/
12.18 DESARROLLO (VER 6)
http://trafficserver.apache.org/docs/v2/sdk/HTTPHeaders.html
http://en.wikipedia.org/wiki/List_of_HTTP_header_fields
http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html
http://www.cs.tut.fi/~jkorpela/http.html
http://tweet.seaofclouds.com/
12.19 USOS ALTERNATIVOS (VER 7)
https://code.google.com/apis/console/
http://www.w3c.es/divulgacion/guiasbreves/accesibilidad
12.20 CONCLUSIONES (VER 8)
https://github.com/dajobe/redland-bindings/pull/2
12.21 LICENCIAS (VER 10)
http://es.wikipedia.org/wiki/MIT_License
http://www.opensource.org/licenses/mit-license.php
http://en.wikipedia.org/wiki/MIT_License
http://es.wikipedia.org/wiki/GNU_General_Public_License
http://en.wikipedia.org/wiki/GNU_General_Public_License
http://www.gnu.org/copyleft/gpl.html
http://es.creativecommons.org/
http://es.creativecommons.org/licencia/
http://creativecommons.org/licenses/by-sa/3.0/
12.22 MANUAL DE USUARIO (VER 13)
http://projects.unbit.it/uwsgi/
http://projects.unbit.it/uwsgi/wiki/RunOnNginx
http://projects.unbit.it/uwsgi/wiki/Example
PROYECTO FIN DE CARRERA
149
http://www.westphahl.net/blog/2010/4/8/running-django-nginx-and-uwsgi/
http://blog.zacharyvoase.com/2010/03/05/django-uwsgi-nginx/
http://blog.martinfjordvald.com/2010/07/nginx-primer/
http://wiki.nginx.org/HttpUwsgiModuleMultipleDynamicApplications
https://gist.github.com/1034260
https://gist.github.com/1034202
https://gist.github.com/1042053
12.23 GLOSARIO (VER 11)
http://es.wikipedia.org
http://en.wikipedia.org
12.24 OTROS
Resaltador de sintaxis: http://www.tohtml.com/
Página de repositorios: https://github.com/
Repositorío GIT del proyecto: https://github.com/slok/metaproxy
PROYECTO FIN DE CARRERA
151
13. MANUAL DE USUARIO
Para la correcta utilización de esta herramienta y sacar todo su potencial es
necesario conocer su funcionamiento. Este manual de usuario tiene como objetivo
principal el de ayudar con el aprendizaje de uso de esta herramienta poder exprimir
todas las características que se le pueden dar al proxy.
Además, también se explicará su puesta en marcha en sistemas GNU/Linux.
Hay que mencionar que también es posible su puesta en marcha en sistemas
Windows, ya que todo lo utilizado para la realización del proyecto ha sido
multiplataforma.
13.1 INSTALACIÓN
La instalación del metaproxy se caracteriza por tener muchas dependencias.
En este manual de usuario se explicará la instalación de algunas de ellas (más
concretamente aquellos que no sean requisitos primarios). Es importante mencionar
que la explicación de la instalación de dependencias que hay a continuación, se trata
de la forma genérica que funcionaría en toda distribución de GNU/Linux. No obstante,
esto no significa que sea la única forma de hacerlo, ya que cada distribución tiene su
propio sistema de paquetes.
13.1.1 Requisitos primarios
Se partirá del supuesto de que los requisitos primarios se encuentran ya
instalados y configurados adecuadamente:
MySQL
Python ( >= 2.5)
Python-MysQL
13.1.2 Requisitos
13.1.2.1 Easy install y pip
(http://pypi.python.org/pypi/setuptools)
En primer lugar, descargamos el archivo egg correspondiente a la versión de
Python que tengamos instalada desde la dirección
13. MANUAL DE USUARIO
152
http://pypi.python.org/pypi/setuptools#downloads y lo ejecutamos. Por ejemplo, para la
versión 2.6 de Python haríamos lo siguiente:
# sh ./setuptools-0.6c11-py2.6.egg
#easy_install pip
Código 13-1: Instalación de setuptools y pip
13.1.2.2 Django
# pip install django
Código 13-2: Instalación Django
13.1.2.3 Restkit
# pip install gunicorn
# pip install http-parser
# pip install restkit
Código 13-3: Instalación Restkit
13.1.2.4 Pygments
# pip install pygments
Código 13-4: Instalación Pygments
13.1.2.5 Beautiful Soup
# pip install BeautifulSoup
Código 13-5: Instalación Beautiful Soup
13.1.2.6 Lxml
# pip install lxml
Código 13-6: Instalación Lxml
PROYECTO FIN DE CARRERA
153
13.1.2.7 Graphviz
$ wget http://www.graphviz.org/pub/graphviz/stable/SOURCES/graphviz-
2.28.0.tar.gz
$ tar xvf graphviz-2.28.0.tar.gz
$ cd ./graphviz-2.28.0
Código 13-7: Obtención del código fuente de Graphviz
Se deberán de compilar las bindigns para Python. Para ello se hará lo
siguiente:
$ ./configure --enable-python=yes
$ make
# make install
Código 13-8: Instalación de Graphviz
13.1.2.8 Python-graph
$ wget http://python-graph.googlecode.com/files/python-graph-
1.8.0.tar.bz2
$ tar xvf ./python-graph-1.8.0.tar.bz2
$ cd ./python-graph-1.8.0
# make install-core
# make install-dot
Código 13-9: Instalación Python-graphviz
13.1.2.9 Redland
13.1.2.9.1 Raptor
Para GRDDL hay que instalar también las librerías libxml2 y libxslt.
$ git clone https://github.com/dajobe/raptor.git
$ cd ./raptor
$ ./configure
$ make
//opcional
[$ make check]
[$ cd ./examples]
[$ make grapper]
[$ make examples]
[$ [ejecutar los ejemplos compilados]]
[$ cd ../]
13. MANUAL DE USUARIO
154
# make install
Código 13-10: Instalación Raptor
13.1.2.9.2 Rasqal
$ git clone https://github.com/dajobe/rasqal.git
$ cd ./rasqal
$ ./configure
$ make
//opcional
[$ make check]
# make install
Código 13-11: Instalación Rasqal
13.1.2.9.3 LibRDF
$ git clone https://github.com/dajobe/librdf.git
$ cd ./redland
$ ./configure --with-mysql
$ make
//opcional
[$ make check]
[$ cd ./examples/]
[$ make examples]
[$ ./example1
http://paginaspersonales.deusto.es/dipina/resources/diego.rdf]
[$ cd ../]
# make install
Código 13-12: Instalación LibRDF
13.1.2.9.4 Redland bindings (Python)
$ git clone https://github.com/dajobe/redland-bindings.git
$ cd ./redland-bindings
$ ./configure --with-python
$ make
$ make check
# make install
//opcional
[$ cd ./python/]
[$ python ./example.py]
[$ cat ./test-out.rdf]
Código 13-13: Imstalación Python Redland bindings
PROYECTO FIN DE CARRERA
155
13.2 ENTORNO DE PRODUCCIÓN
La puesta en marcha en entornos de producción se ha hecho sobre Nginx. Sin
embargo, también se puede hacer sobre cualquier otro como Apache, lighttp… En esta
sección del manual de usuario se indicará cómo proceder para la puesta en marcha de
la herramienta usando Nginx.
13.2.1 Requisitos
Nginx (>= 1.0.0)
uWSGI (>=0.9.1)
13.2.2 Se presupone
Todas las dependencias están satisfechas.
Instalación correcta de Nginx (permisos, usuarios, versión correcta…).
Instalación correcta de uWSGI.
Ruta del proyecto: /www/var/nginx/metaproxy
Ruta de archivo de configuración de Nginx: /etc/nginx/nginx.conf
Los scripts están editados para que funcionen con las rutas (se especificará
cuando se deberá cambiar).
13.2.3 Configurar Nginx
Editamos el archivo de configuración de Nginx para que sea algo similar a lo
que se muestra a continuación (la ruta /var/www/nginx/metaproxy se deberá
cambiar por la localización del proyecto, así como también el usuario y grupo de Ngix):
user nobody nobody;
worker_processes 1;
#error_log logs/error.log;
#error_log logs/error.log notice;
#error_log logs/error.log info;
#pid logs/nginx.pid;
events {
worker_connections 1024;
}
http {
include mime.types;
default_type application/octet-stream;
#log_format main '$remote_addr - $remote_user [$time_local]
"$request" '
13. MANUAL DE USUARIO
156
# '$status $body_bytes_sent "$http_referer" '
# '"$http_user_agent" "$http_x_forwarded_for"';
#access_log logs/access.log main;
sendfile on;
#tcp_nopush on;
#keepalive_timeout 0;
keepalive_timeout 65;
#gzip on;
server {
listen 80;
server_name localhost;
root /var/www/nginx/metaproxy ;
#autoindex on;
#charset koi8-r;
#access_log logs/host.access.log main;
# Your project's static media.
location /static {
alias /var/www/nginx/metaproxy/static;
}
location / {
#Config for Django and uWSGI project
uwsgi_pass unix:/tmp/uwsgi-metaproxy.sock;
include uwsgi_params;
}
}
}
Código 13-14: Archivo de configuración de Nginx
13.2.4 Añadir configuración de Django uWSGI
Añadimos el siguiente script con el nombre django.wsgi en el directorio del
proyecto (/var/www/nginx/metaproxy).
# django.wsgi
import sys
import os
sys.path.append(os.path.abspath(os.path.dirname(__file__)))
os.environ['DJANGO_SETTINGS_MODULE'] = 'metaproxy.settings'
import django.core.handlers.wsgi
application = django.core.handlers.wsgi.WSGIHandler()
Código 13-15: Configuración de Django para uWSGI
PROYECTO FIN DE CARRERA
157
13.2.5 Script para hacer deploy de aplicaciones Django
Este script hace deploy de todas las aplicaciones Django en un mismo
directorio, así como hacer que estén configuradas correctamente para hacerlo con
uWSGI. El script se guardará en la raiz de los proyectos con el nombre
deployAllDj.sh (en este caso la ruta será /var/www/nginx).
#!/bin/bash
# deployAllDj.sh: This scripts executes all the uwsgi scripts in the
Django projects(project's path) that are ready
# to be deployed, by this way we can deploy all the Django apps
automatically and not one by one
#
# Author: Xabier Larrakoetxea (slok) <[email protected]>
# Iraide Diaz (sharem) <[email protected]>
#
# License: This script is in public domain.
#MODIFY THIS!!
SEARCH_PATH=/var/www/nginx
SCRIPT_NAME=uwsgi.sh
DIRLIST=$(find $SEARCH_PATH -type d -maxdepth 1 -mindepth 1 )
for DIR in $DIRLIST
do
if [ -x $DIR/$SCRIPT_NAME ]; then
$DIR/$SCRIPT_NAME
fi
done
Código 13-16: Script para deploy de aplicaciones Django con uWSGI
13.2.6 Script de ejecucucíon uWSGI
Este script ejecutará el comando necesarío para abrir el socket uWSGI con el
que Nginx servirá la aplicación. Se guardará en la raiz del proyecto
(/var/www/nginx/metaproxy) con el nombre uwsgi.sh. Asimismo, se deberán
modificar dos variables:
PYTHON_PATH con el directorio a la raiz de los proyectos, que en este caso es
/var/www/nginx
WSGI_CONF_NAME con el nombre de la configuración uwsgi, que en este caso
es django.wsgi
#!/bin/bash
# uwsgi.sh: This script executes the uwsgi command needed to deploy
the Django app for example for Nginx.
# The only things needed that have to be changed are the PYTHON_PATH
13. MANUAL DE USUARIO
158
and WSGI_CONF_NAME variables
# NOTE: The script must be inside the Django project(root folder)
#
# Author: Xabier Larrakoetxea (slok) <[email protected]>
# Iraide Diaz (sharem) <[email protected]>
#
# License: This script is in public domain.
#MODIFY THIS!
PYTHON_PATH=/var/www/nginx
WSGI_CONF_NAME=django.wsgi
#Get the current dir name (last part)
CURRENT_DIR=$(pwd)
SCRIPT_DIR=$(dirname $0)
if [ $SCRIPT_DIR = '.' ]
then
SCRIPT_DIR="$CURRENT_DIR"
fi
SCRIPT_DIR=`basename $SCRIPT_DIR`
#SCRIPT_DIR=${SCRIPT_DIR##*/}
#Used variables
NAME=$SCRIPT_DIR
SOCKET=/tmp/uwsgi-$NAME.sock
PROJECT_DIR=$PYTHON_PATH/$NAME
WSGI_FILE=$PROJECT_DIR/$WSGI_CONF_NAME
PID=/tmp/uwsgi-$NAME.pid
LOG_FILE=/tmp/uwsgi-$NAME.log
#command
uwsgi --chdir $PROJECT_DIR \
--processes 1 \
--chmod-socket \
--socket $SOCKET \
--wsgi-file $WSGI_FILE \
--pythonpath $PYTHON_PATH \
--pidfile $PID \
--daemonize $LOG_FILE \
--harakiri 20 \
--master \
--vacuum \
--max-requests=5000 \
--memory-report \
--sharedarea 4
#--limit-as=128 \
#--module='django.core.handlers.wsgi:WSGIHandler()' \ #We don't
need if we had wsgi config file
#--env DJANGO_SETTINGS_MODULE=settings \ #We don't need if we
had wsgi config file
#--home=/path/to/virtual/env \ # optionnal path to a virtualenv
echo "--------------------------------------"
echo "UWSGI STARTED FOR $NAME DJANGO PROJECT"
echo ""
echo "Socket path: $SOCKET"
PROYECTO FIN DE CARRERA
159
echo "Log path: $LOG_FILE"
echo "PID: `cat $PID`"
echo ""
Código 13-17: Script de comando uWSGI
13.2.7 Configuración Django
Para que el proyecto funcione correctamente, antes de arrancar todo, se
deberá configurar la aplicación de Django (en concreto la base de datos). Para ello:
En Settings.py dentro de la raíz del proyecto se deberá modificar el
nombre y el password del usuario de la base de datos.
'USER': 'django', # Not used with sqlite3.
'PASSWORD': 'django',
Código 13-18: Usuario y clave de la BD en settings.py
Asimismo, también se deberá cambiar el usuario y password de la base de
datos en manager/views.py:
dbUser='xxxxxxxx'
dbPass='xxxxxxxxxxxx'
Código 13-19: Usuarío y clave de la BD en manager/views.py
13.2.8 Crear base de datos para Django
La base de datos de Django debería estar creada con las herramientas
correspondientes de MySQL, además del usuario con permisos para escribir, ejecutar
consultas y actualizar sobre ella. Una vez que se tenga esto, bastará con entrar en el
directorio del proyecto y ejecutar este comando para la creación de las tablas
necesarias en la base de datos por Django:
python manage.py syncdb
Código 13-20: Comando para la creación de las tablas de Django en la BD
13.2.9 Ejecución en modo producción
Para la ejecución en modo producción de la aplicación, se deberían ejecutar
dos cosas:
El servidor Nginx
13. MANUAL DE USUARIO
160
La aplicación mediante uWSGI
Los pasos a seguir para la ejecución del demonio de Nginx, dependerán del
propio sistema donde se ejecute. No obstante, por ejemplo, podría ser algo similar a lo
siguiente:
# /etc/rc.d/rc.nginx start
Código 13-21: Comando para arrancar demonio de Nginx
Para arrancar la aplicación mediante uWSGI, basta con arrancar el script
llamado uwsgi.sh que se ha creado dentro del directorio del proyecto. Sin embargo,
para arrancar multiples aplicaciones usaremos el otro script que hemos creado en el
directorio donde están todas las aplicaciones de Django (en este caso sólo es
necesario arrancar una aplicación, pero este script también vale). Para ello ejecutamos
lo siguiente:
$ /var/www/nginx/deployAllDj.sh
Código 13-22: Comando para arrancar script de deploy
PROYECTO FIN DE CARRERA
161
13.3 USO
13.3.1 Página principal
En la imagen que se muesta a continuación, se puede observal la página
principal de portal web del proyecto. Ésta tiene varios puntos que son importantes, los
cuales se detallarán seguidamente:
Como se puede apreciar, el menú de la parte superior de la página tiene varias
opciones. Entre ellas están:
Home: Link que apunta a la página principal.
Manager: Desde este link se podrá acceder a la lógica y configuración del
servidor proxy (RDF, Web, Queries SPARQL…).
Admin: Desde este link se podrá acceder a la parte de administración de
usuarios de la página.
Por otro lado, desde la siguiente lista de links será desde donde se podrá
acceder a las páginas que el proxy servirá. Todas las páginas que se registren podrán
ser accedidas desde este punto.
Ilustración 13-1: Página principal
Ilustración 13-2: Menú de la página principal
13. MANUAL DE USUARIO
162
Asimismo, para poder acceder al repositorio alojado en Github con todo el
código fuente tan sólo es necesario acceder mediante esta pequeña cinta que se
encuentra en la esquina superior derecha de la página principal.
13.3.2 Sección administración de la página web
Ilustración 13-4: Acceso al repositorio online con el código fuente
Ilustración 13-5: Login de la administración de la web
Ilustración 13-3: Páginas registradas en el proxy
PROYECTO FIN DE CARRERA
163
Para poder entrar a la parte de administración de la web (o al administrador de
Django) es necesario pasar por la pantalla de login. Por eso cuando se intenta
acceder a la sección admin si no nos hemos logueado habrá que meter un usuario y
password válidos.
Una vez autenticado, el usuario podrá ejercer varias acciones sobre los
usuarios como añadir nuevos usuarios, listarlos, borrarlos, etc…
Ilustración 13-7: Añadir nuevo usuarios
Ilustración 13-6: Pantalla principal del panel de adminsitración de la web
13. MANUAL DE USUARIO
164
Como se puede apreciar en la imagen, el panel para añadir un nuevo usuario
tiene tres campos obligatorios que se deben rellenar: el nombre de usuario, su
password y la verificación de este último.
Desde la lista de usuarios se pueden acceder y cambiar todos los detalles de
cada usuario registrado. Los datos que se pueden visualizar de los usuarios son
variados, como por ejemplo el Email, nombre, apellido, grupo al que pertenecen...
13.3.3 Sección Administrador proxy
Como ocurre con el panel de administración de web, antes de acceder al
administrador proxy o Manager deberemos loguearnos. Una vez hecho esto,
podremos acceder al menú.
Ilustración 13-9: Zoom de la lista de usuarios
Ilustración 13-8: Lista de usuarios
PROYECTO FIN DE CARRERA
165
Cuando se entra en la sección donde se adminsitrará el proxy, aparecerá un
menú donde se podrá elegir a qué sección queremos acceder. Las opciones entre las
cuales elegir son las siguientes:
Ilustración 13-10: Menú de administración del proxy (Manager)
Ilustración 13-11: Login administrador proxy
13. MANUAL DE USUARIO
166
RDF
Ontologies
SPARQL Queries
Scripts
Web pages
13.3.3.1 RDF
Para poder guardar los archivos RDF en la base de datos y posterioremente
poder consultarlos, primero habrá que insertarlos con las herramientas
corresponientes. Para eso está el panel de inserción de RDF.
El RDF Uploader da la opción de poder subir el archivo RDF al servidor proxy
de dos formas. La primera de ellas, es seleccionando un archivo que se encuentra en
la máquina local:
Ilustración 13-13: RDF Uploader
Ilustración 13-12: Iconos del menú del Manager
PROYECTO FIN DE CARRERA
167
Si pulsamos en el botón de “Examinar”, a continuación nos aparecerá una
ventana donde deberemos seleccionar el archivo RDF que queremos subir.
Por otro lado, la segunda opción para subir un archivo RDF es la descarga de
éste último desde una página web. Para ello, únicamente deberemos indicar la
dirección web completa donde se encuentra alojado ese archivo RDF.
Ilustración 13-16: Descargar archivo RDF
Ilustración 13-15: Selección del archivo RDF local
Ilustración 13-14: Subir archivo RDF desde la máquina local
13. MANUAL DE USUARIO
168
Una vez se haya elegido el archivo RDF a subir por medio de alguno de los dos
métodos mencionados anteriormente, a continuación se deberá seleccionar la base de
datos donde se guardará. Cada base de datos corresponde a una de las páginas ya
registradas en el servidor proxy. Para facilitar su identificación, su nombre será su
dirección web correspondiente.
Despues de completar todos los campos, habrá que pulsar el botón de
“submit”. Al hacer esto, si la operación ha sido exitosa, saldrá una página diciendo que
la inserción del archivo en la base de datos ha sido correcta:
13.3.3.2 Ontologías
Las ontologías van en forma de links, lo que significa que se almacenan en la
base de datos en forma de clave-valor, o lo que es lo mismo, un identificador y un
enlace a la ontología en sí.
Ilustración 13-17: Selección de la base de datos donde almacenar el archivo RDF
Ilustración 13-18: Página de inserción en base de datos correcta
PROYECTO FIN DE CARRERA
169
Como se ve en la imagen, la página de ontologías es bastante simple y está
compuesta de varios campos para la inserción de estos. El primero de todos, es el
nombre de la ontología:
El nombre que se le de a la ontogía que se quiera insertar, deberá ser un
identificativo claro, como por ejemplo: “Dublin Core”. A continuación, se deberá
rellenar el link correspondiente a la ontología. Este link suele estar siempre presente
en los archivos RDF, de forma que desde el RDF se pueda identificar la ontología
usada.
Por último, la página tiene un listado con todas las ontologías guardadas en la
base de datos.
Ilustración 13-20: Inserción del nombre de la ontología
Ilustración 13-21: Inserción del enlace a la ontología
Ilustración 13-19: Página para la inserción de ontologías
13. MANUAL DE USUARIO
170
13.3.3.3 Queries SPARQL
De la misma forma que se hacen las consultas SQL en las bases de datos
normales, para la consulta de metadatos se usan consultas SPARQL. Para ello, el
administrador del proxy tiene una sección donde poder ejecutar esas consultas y
obtener un resultado.
Ilustración 13-22: Listado de ontologías almacenadas
Ilustración 13-23: Consultas SPARQL
PROYECTO FIN DE CARRERA
171
Para poder realizar una consulta SPARQL se deben rellenar varios campos (al
igual que se ha hecho con los demás formularios anteriores). En primer lugar hay que
seleccionar la base de datos en la que se quieren hacer las consultas.
Despues de haber seleccionado la base de datos donde se ejecutará la
consulta, se tendrá que seleccionar el formato en el que se desee que aparezca el
resultado (es importante mencionar que por ahora sólo está habilitado el más usado:
RDF/XML).
Por último, sólo faltaría añadir la query o consulta que deseásemos realizar,
escribiéndola en el siguiente recuadro y darle al botón de “submit”.
Un ejemplo de una query en SPARQL podría ser la que se muestra a
continuación. Esta query en concreto, comprueba las relaciones de amigos con la
ontología FOAF:
PREFIX foaf: <http://xmlns.com/foaf/0.1/>
SELECT ?aname ?bname WHERE
{
?a foaf:knows ?b . ?a foaf:name ?aname . ?b foaf:name ?bname .
}
Código 13-23: Ejemplo de query SPARQL
Ilustración 13-25: Selección del formato para los resultados
Ilustración 13-26: Caja de texto para la query SPARQL
Ilustración 13-24: Selección de la base de datos en la que realizar la consulta
13. MANUAL DE USUARIO
172
Despues de darle al botón de “submit”, la query será ejecutada en la base de
datos elegida, el resultado será formateado adecuadamente en el tipo de formato de
salida elegido y lo devolverá en una nueva página con coloreado de sintaxis para que
su visualización sea mejor.
13.3.3.4 Scripts
Para que el proxy cambie su comportamiento, se deberán de subir los scripts
que provoquen ese cambio al servidor proxy. Cabe destacar que existe un script por
defecto que se le asigna a una página una vez que ésta es registrada en sel servidor
Ilustración 13-27: Resultado de la consulta (query) en la base de datos
Ilustración 13-28: Administración de scripts
PROYECTO FIN DE CARRERA
173
proxy. De todos modos, para la creación de scripts personalizados se proporciona una
pequeña API19 en este proyecto.
Para guardar un script en el servidor proxy, lo primero que hay que hacer es
localizar el archivo del script y subirlo mediante el formularío que se proporciona,
rellenando para ello varios campos:
Tras seleccionar el archivo, se deberá seleccionar a qué página (previamente
registrada en el servidor) se quiere asociar.
Por otro lado, al final de la página de esta sección, se encuentra un listado con
los scripts principales asociados a cada una de las páginas registradas.
19
Ver página 85 para más información sobre la API.
Ilustración 13-29: Selección del archivo del script
Ilustración 13-30: Selección de la página a la que pertenecerá el script
Ilustración 13-31: Scripts de cada página del proxy
13. MANUAL DE USUARIO
174
En cada una de las filas, existe un icono debajo de la columna “Script”, en el
cual se podrá pulsar para que aparezca en una página aparte el visualizador del
código. En este visualizador se podrá ver el script seleccionado con resaltado de
sintaxis para su correcta y cómoda lectura al igual que en el caso de los resultados de
la consulta SPARQL.
13.3.3.5 Webs
Desde el panel de administración de webs, se podrán agregar las webs a las
cuales se podrá acceder para que el servidor pueda hacer de proxy de ellas. Como se
ha indicado antes, al añadir una página web al servidor proxy, en un principio se le
Ilustración 13-32: Visualizador de scripts
Ilustración 13-33: Administrador de páginas web del proxy
PROYECTO FIN DE CARRERA
175
asociará el script por defecto, ya incluido en el propio proyecto. De todos modos,
posteriormente se podrá usar el administrador de scripts para substituirlo por otro
script personalizado.
Para añadir una nueva página web al servidor, se deberán rellenar una seríe de
campos como se ha ido haciendo hasta ahora.
En el primer campo que se muesta a continuación, irá el identificador de la
página web. Por ejemplo, si queremos registrar la página de Google podríamos
introducir simplemente “Google” en él.
En el siguiente campo se deberá insertar el enlace a la página web. Por
ejemplo, retomando el ejemplo anterior introduciríamos lo siguiente:
“http://www.google.com”
Por último, esta página tiene un listado donde aparecen todas las páginas que
actualmente están registradas en el proxy. Cada página tiene un botón a modo de
Ilustración 13-34: Identificador de la página
Ilustración 13-35: Enlace de la página web
Ilustración 13-36: Listado de las páginas registradas en el proxy
13. MANUAL DE USUARIO
176
imagen de papelera, debajo de la columna “Delete”, en el que haciendo click eliminará
la página correspondiente, incluyendo su script asociado.
13.3.4 Ejemplos sobre el proyecto
Previamente se han explciado los scripts existentes en el proyecto20 dento del
ámbito de la programación y de la API. Sin embargo, no se han mostrado imágenes de
lo que un usuario puede ver en el navegador, como resultado de la ejecución de estos
scrips.
13.3.4.1 Slok
Este script, a parte de añadir un botón para regresar a la página principal del
proxy, lo que hace es añadir un visualizador de tweets hecho en JavasScript, el cual
se va actualizando periódicamente con los mensajes recibidos de la cuenta asociada.
13.3.4.2 Dbujan
20
Ver punto 6.1.3 para más información acerca de la programación de los scripts existentes en el proyecto.
Ilustración 13-37: Página con un visualizador de tweets
PROYECTO FIN DE CARRERA
177
Este script se ejecuta sobre la página personal ed Deusto del profesor David
Buján. Básicamente lo que hace es cambiarle el aspecto a la página (más
concreatmente, sustituye su CSS actual por otro nuevo), devolviéndola en tonos
grisáceos.
13.3.4.3 Dipina
La página de Diego Lopez de Ipiña utiliza el script por defecto. Por lo tanto, se
Ilustración 13-38: Página personal de David Buján
Ilustración 13-39: Página dipina
13. MANUAL DE USUARIO
178
encarga de sacar y manejar los metadatos existentes en su página para
posteriormente visualizarlos adecuadamente.
En primer lugar, este script lo que hace es añadir a la página original una serie
de pestañas, donde la primera de ellas, será la página original en sí. Seguidamente,
existirán una serie de pestañas que se crearán una por cada archivo RDF encontrado
en la página original. Por último, si la página contiene GRDDL, al final de todas las
pestañas aparecerá una pestaña de GRDDL.
En la imagen anterior podemos observar como claramente existen dos
pestañas en la parte superior de la página proxy: una con la página original y la otra
con un archivo RDF que ha detectado dentro de ella.
Ilustración 13-40: Vista de RDF en XML
Ilustración 13-41: Grafo a partir del RDF/XML
PROYECTO FIN DE CARRERA
179
En estas otras imágenes, se puede ver el contenido de pestaña generada por
ese archivo RDF detectado. Como se puede apreciar, el archivo RDF detectado es
visualizado de dos formas: en forma de código, con resaltado de sintaxis y a modo de
grafo.
13.3.4.4 GRDDL
La página de Dr. Diego López de Ipiña no incluía GRDDL por defecto, así que
para poder porbar esta funcionalidad cogimos partes de su página web y las
modificamos para poder insertarle GRDDL. A continuación, esa página modificada se
subió a nuesto servidor para poder comprobarla como proxy. Además de eso, se le
añadieron más archivos RDF para poder demostrar que efectivamente, el script crea
una pestaña por cada archivo RDF encontrado en la página solicitada.
Como se puede apreciar en la imagen superior, se han detectado varios
archivos RDF y se ha creado una pestaña por cada uno de ellos. Además, también
está la pestaña por defecto donde sale la página principal y una pestaña más al final
(GRDDL Parsing) que será la correspondiente a GRDDL.
Al igual que la página original del Dr. Diego López de Ipiña, la imagen que se
muestra a continuación es también uno de los RDF detectados en formato XML.
Ilustración 13-42: Demostración de GRDDL
13. MANUAL DE USUARIO
180
Por otro lado, el grafo correspondiente al XML previamente mostrado es el
siguiente:
A partir del GRDDL detectado en la página original, en la pestaña GRDDL se
genera un RDF/XML como resultado. Éste se visualiza de la misma forma que los RDF
normales:
Ilustración 13-43: XML de RDF
Ilustración 13-44: Grafo de RDF
PROYECTO FIN DE CARRERA
181
Por último, el grafo generado a partir del RDF/XML que a su vez ha sido
generado de GRDDL en la página web. El grafo también esta en la pestaña GRDDL
debajo del código XML.
Ilustración 13-45: XML generado a partir de GRDDL
Ilustración 13-46: Grafo a partir de RDF/XML del GRDDL