• No results found

Implementación de una aplicación web dirigida a directorios de profesionales del sector del taturaje

N/A
N/A
Protected

Academic year: 2022

Share "Implementación de una aplicación web dirigida a directorios de profesionales del sector del taturaje"

Copied!
83
0
0

Laster.... (Se fulltekst nå)

Fulltekst

(1)

Escola Politècnica Superior Memòria del Treball de Fi de Grau

Implementación de una aplicación web dirigida a directorios de profesionales del sector del

tatuaje

Carlos Tenorio Pérez

Grau de Edificació Enginyeria Informàtica

Any acadèmic 2016-17

DNI de l’alumne: 43192862N

Treball tutelat per Carlos Guerrero Tomé

Departament de Ciencias Matemáticas e Informática

S'autoritza la Universitat a incloure aquest treball en el Repositori Institucional per a la seva consulta en accés obert i difusió en línia, amb finalitats exclusivament acadèmiques i d'investigació

Autor Tutor

No No

X X

Paraules clau del treball:

Web, Django, Docker, Nginx, Gunicorn

(2)
(3)

A mi familia por ayudarme en todo lo posible para poder acabar la carrera en los momentos más duros.

A mi tutor Carlos Guerrero Tomé por su ayuda y consejos a lo largo de los últimos años donde he podido apreciarlo como profesor y como persona.

A Camila Pérez Arévalo y Joan Martín Miralles, por acompañarme en estos años universitarios donde he podido descubrir verdaderas amistades y sin ellos mi paso por la UIB no hubiese sido igual.

A mis abuelos, por guiarme siempre en la mejor dirección y estar siempre a mi lado.

(4)
(5)

Í NDICE GENERAL

Índice general iii

Índice de figuras vii

Acrónimos ix

Resum xi

1 Inroducción 1

1.1 Marco del proyecto . . . 1

1.2 Alternativas y competencia . . . 1

1.3 Objetivos . . . 2

2 Conceptos tecnológicos 3 2.1 AJAX . . . 3

2.2 Docker. . . 3

2.3 Docker Compose . . . 5

2.4 Servidor WSGI . . . 5

2.5 GIT. . . 5

2.6 Kanvan . . . 5

2.7 PostgreSQL . . . 6

2.8 PgAdminIII . . . 6

2.9 Django. . . 6

2.10 NodeJs. . . 6

2.11 Gulp . . . 6

2.12 Bower . . . 6

2.13 Bootstrap . . . 7

2.14 Nginx . . . 7

2.15 Gunicorn . . . 7

2.16 Memcached . . . 7

3 Arquitectura de la aplicación 9 3.1 Docker - Docker Compose . . . 9

3.1.1 Desarrollo . . . 9

3.1.2 Producción . . . 12

3.2 Diagrama de la arquitectura . . . 13

3.3 Arquitectura dentro delFramework Django . . . 14

(6)

iv ÍNDICE GENERAL

4 Base de datos 17

4.1 Modelo UML . . . 17

4.2 Clases y relaciones. . . 17

4.2.1 Geolocalización del usuario . . . 17

4.3 PotgreSQL. . . 19

4.4 PgAdminIII . . . 20

5 Backend 21 5.1 NodeJS . . . 21

5.2 Gulp . . . 21

5.3 Django. . . 22

5.3.1 MVP (Modelo-Vista-Plantilla) . . . 24

5.3.2 Desacoplamiento de las variables sensibles . . . 24

5.4 Logs . . . 25

5.5 Integración de la API deInstagram . . . 25

5.5.1 Introducción . . . 25

5.5.2 Permisos . . . 25

5.5.3 Social-Auth y acceso al contenido multimedia . . . 26

5.5.4 Pipelines. . . 29

6 Frontend 31 6.1 Bower . . . 31

6.2 Bootstrap . . . 32

6.3 CSS3/Less. . . 32

6.4 Django template . . . 32

6.5 AJAX . . . 34

7 Puesta en producción 37 7.1 Ngnix . . . 37

7.2 Gunicorn . . . 38

7.3 Automatización del despliegue con GIT . . . 39

8 Administración 41 8.1 Panel de control . . . 41

8.2 Estadísticas . . . 43

9 Automatización del aplicativo 45 9.1 Automatización en el desarrollo . . . 45

9.1.1 Carga de la base de datos . . . 45

9.2 Automatización en la producción . . . 46

9.2.1 Puntuaciones de los profesionales. . . 46

10 Principales funcionalidades de la web 47 10.1 Acciones de un usuario anónimo . . . 47

10.2 Acciones de un usuario . . . 51

10.3 Acciones de un profesional. . . 52

11 Metodología 59

(7)

ÍNDICE GENERAL v

11.1 Sistema de control de versiones . . . 59

11.2 Kanban . . . 59

12 Modelo de negocio 61 12.1 Introducción . . . 61

12.2 Socios claves . . . 61

12.3 Segmento de cliente. . . 61

12.4 Propuesta de valor. . . 62

12.5 Canales de distribución. . . 62

12.6 Relaciones con clientes . . . 62

12.7 Actividades claves . . . 63

12.8 Recursos claves . . . 63

12.9 Estructura de costes. . . 64

12.10 Fuente de ingresos. . . 64

13 Conclusiones 65 13.1 Conclusión . . . 65

13.2 Acciones futuras . . . 65

Bibliografía 67

(8)
(9)

Í NDICE DE FIGURAS

3.1 Contenedores con Bower, Gulp y Npm dependientes del contenedor Node.js. 10

3.2 Interacción entre el desarrollador, el contenedordevy la base de datos. . . 10

3.3 Sistema desplegado en producción a través de contenedoresDocker. . . . . 13

3.4 Diagrama general de la arquitectura de la web y las conexiones bidireccio- nales pertinentes. . . 15

4.1 Modelo Lenguaje de Modelado Unificado (UML) de la base de datos de Tinta y Piel.. . . 18

5.1 Elección si eres tatuador o no en la URL signup_instagram . . . 26

5.2 Formulario para los profesionales una vez autenticados con su cuenta de Instagram.. . . 27

5.3 Perfil de un profesional recién registrado a través de su cuenta de Instagram 27 5.4 Selección de las fotos más recientes de la cuenta de Instagram que se desean subir a la web . . . 28

7.1 Interacción del servidorWSGI Guncironcon el módulo de integración de Django. . . 38

7.2 Diagrama de flujo del proceso de desligue de nuevas funcionalidades en producción. . . 40

8.1 Vista de edición de un profesional en el panel de administración . . . 42

8.2 Inició de sesión en el portal de administración de Tinta y Piel . . . 42

8.3 Tabla en el panel del administración para que unsuperusuariopueda otorgar determinados permisos a un usuario.. . . 43

8.4 Histórico de acciones de un profesional realizadas desde el panel de admi- nistración.. . . 43

8.5 Gráficas del número de registros de usuarios y profesionales en el sistema. 44 10.1 Formulario de registro para que un usuario pueda pasar a pertenecer al sistema y dejar de ser anónimo. . . 48

10.2 Visualización de los profesionales situados en Palma de Mallorca.. . . 48

10.3 Preguntas frecuentes de la webTinta y Pielen la sección de Ayuda. . . 50

10.4 Formulario para ponerse en contacto con el equipo deTinta y Piel. . . . 50

10.5 Mensaje de advertencia sobre lascookiesdel portal web. . . 51

10.6 Formulario para realizar una opinión acerca de un profesional. . . 51

10.7 Formulario para realizar una opinión acerca de un profesional. . . 52

10.8 Visualización de una opinión con 1útilasignado. . . 52

(10)

viii Índice de figuras

10.9 Modal para subir fotos desde el ordenador al perfil de un profesional. . . . 53 10.10 Menú desplegable de edición para las fotos subidas por un profesional. . . 54 10.11 Modal para un profesional pueda crear un nuevo álbum. . . 54 10.12 Menú desplegable de edición para los álbumes creados por un profesional. 55 10.13 Modal para cambiar la foto de perfil de un profesional. . . 56 10.14 Visualización de un usuario con prioridad en una búsqueda con ordenación

por la puntuación media total.. . . 57 11.1 Tablero Kanban utilizado para la organización del trabajo a realizar en la

webTinta y Piel. . . . 60

(11)

A CRÓNIMOS

ACID Atomicity, Consistency, Isolation and Durability AJAX Asynchronous JavaScript And XML

API Application Programming Interface BSD Berkeley Software Distribution CGI Common Gateway Interface GIF Graphics Interchange Format HTML HyperText Markup Language HTTP Hypertext Transfer Protocol IMAP Internet Message Access Protocol JPEG Joint Photographic Experts Group JSON JavaScript Object Notation LXC LinuX Containers

MVC Modelo Vista Controlador NPM Node Package Manager PNG Portable Network Graphics POP3 Post Office Protocol PWA Progressive Web Apps

REST Representational State Transfer SQL Structured Query Language TPV Terminal Punto de Venta TFG Trabajo Final de Grado URL Uniform Resource Locator XML Extensible Markup Language

(12)

x ACRÓNIMOS

XSS Cross-Site Scripting

UML Lenguaje de Modelado Unificado VPS Servidor Privado Virtual

WSGI Web Server Gateway Interface

(13)

R ESUM

Desde el 2008 hasta la actualidad, las búsquedas por Internet de tatuadores se han multiplicado exponencialmente, indicándonos que el interés ha aumentado constan- temente a lo largo del tiempo, especialmente entre la gente joven. Los tatuajes se encuentran en auge y hay estimaciones que aseguran que un 20 % de los adultos en España tiene algún tatuaje [1].

Antes de iniciar el proyecto se realizaron encuestas a tatuadores locales para poder extraer una lista de requisitos básicos con los que poder moldear el modelo de negocio y las principales funcionalidades del portal web.

En este Trabajo Final de Grado (TFG) se presenta el proceso de implementación del portal webTinta y Piel, un buscadoronlinede profesionales del sector del tatuaje que permite a cualquier usuario buscar los tatuadores registrados enTinta y Pielque se encuentran en una ciudad o provincia del territorio español.

Tinta y Pielesta pensado como un comparador donde los usuarios puedan ver las opiniones de otros usuarios acerca de un profesional y poder valorar ellos mismos los trabajos que se encuentran expuestos en el perfil del tatuador.

(14)
(15)

C

APÍTULO

1

I NRODUCCIÓN

1.1 Marco del proyecto

El sector del tatuaje en España ha experimentado un importante auge en los últimos años, generando más de 1 millón de euros al año y alrededor de 2.000 tatuajes al día [2].

Este aumento de la demanda de tatuajes en los dos último años ha provocado que la creación de serviciosonlinerelacionados con el sector del tatuaje no esté comple- tamente satisfecha. Actualmente encontramos pocos portales que ofrezcan servicios relacionados con este tipo de profesionales.

De esta manera, surgió la motivación para crear un portal web que sirviese a los profesionales para poder integrarse dentro del posicionamiento web. Así, de manera paralela también se buscaba ofrecer a los usuarios un buscador donde encontrar a los profesionales del tatuaje más cercanos a su zona.

Un punto clave de cualquier buscadoronlinees poder comparar los servicios que se buscan. Por esa razón, se pensó en integrar un sistema de puntuaciones y opiniones basado en la webTripadvisor[3].

Se eligió como modelo de buscadorTripadvisorporque el sector de la restauración puede extrapolarse de manera fácil al sector del tatuaje, donde las opiniones de otros usuarios son un punto crucial para que el cliente tome la decisión final en su elección.

1.2 Alternativas y competencia

En la actualidad existen diversos portales web que cumplen una función similar aTinta y Piely que pueden suponer una competencia directa al proyecto.

Las principales alternativas a nuestro portal web son:

Inkonsky[4]: portal web de tatuadores que permite compartir imágenes desde Instagram. Esta orientada a ser una red social de profesionales. Es la página web mejor posicionada en los buscadores actualmente dentro del mundo del tatuaje.

(16)

1. INRODUCCIÓN

Inkstinct[5]: aplicación móvil paraAndroideiOSque permite buscar tatuadores por zonas y visualizar tatuajes categorizados por estilos. Es nuestra competencia más directa en funcionalidades debido a que se encuentran implementadas de manera similar aTinta y Piel.

Tattoo Filter[6]: directorio de tatuajes que permite buscarlos categorizados por partes del cuerpo o estilos. Carece de una búsqueda por zona.

1.3 Objetivos

El objetivo principal del proyecto de esteTFGes diseñar y crear un buscadoronlinede profesionales del sector del tatuaje. El portal web también debe ser compatible con dispositivos móviles y tabletas con sistemasAndroideiOS.

La idea principal es poder crear un aplicativo que se pueda poner en producción y que mediante el diseño de un modelo de negocio sostenible se pueda llegar a convertir en una empresa tecnológica emergente.

Se debe crear también una documentación que incluya las explicaciones necesarias para entender la dinámica de la web y los objetivos que marcan el proyecto.

2

(17)

C

APÍTULO

2

C ONCEPTOS TECNOLÓGICOS

Es este capítulo trataremos todos los aspectos teóricos que se requieren para poder entender de manera clara y concisa todo el documento sin que se pierda ningún detalle técnico. Los conceptos descritos abarcan diferentes áreas de conocimiento técnico y de gestión empresarial.

Se tratarán los conceptos de manera teórica y didáctica sin entrar en detalle de como se ha implementado ese concepto en nuestro aplicativo, puesto que eso se tratará en sus respectivos apartados.

2.1 AJAX

Es una técnica de desarrollo web para crear aplicaciones dinámicas. Permite, mediante programas escritos enJavascript, que un servidor y un navegador intercambien infor- mación, en Extensible Markup Language (XML), HyperText Markup Language (HTML) o JavaScript Object Notation (JSON), de forma asíncrona.

2.2 Docker

Docker [7] es un proyecto de código abierto con el que fácilmente podremos crear

’contenedores’virtuales. Estos podríamos definirlos como máquinas virtuales ligeras.

Las características principales de estos contenedores son la portabilidad, la ligereza y la autosuficiencia:

Respecto a la portabilidad, podremos desplegarlos en cualquier sistema (que so- porte esta tecnología) comoLinux,WindowsoMacOS, con lo que nos ahorraremos el tener que instalar en este nuevo entorno todas aquellas aplicaciones que normalmente usemos.

Además supone una ligereza importante en la infraestructura del sistema. El pe- so de este sistema no tiene comparación con cualquier otro de virtualización más convencional que estemos acostumbrados a usar.

(18)

2. CONCEPTOS TECNOLÓGICOS

Por poner un ejemplo, una de las herramientas de virtualización más extendida esVirtualBox, y cualquier imagen deUbuntu[8] que queramos usar en otro equipo pesará entorno a 1Gb si contamos únicamente con la instalación limpia del sistema. En cambio, conDockerunUbuntuconApachey una aplicación web, tiene un tamaño de 180MB, lo que nos demuestra un significativo ahorro a la hora de almacenar diversos contenedores que podamos desplegar con posterioridad.

En la autosuficiencia, un contenedorDockerno contiene todo un sistema com- pleto, sino únicamente aquellas librerías, archivos y configuraciones necesarias para desplegar las funcionalidades que contenga. Asimismo,Dockerse encarga de la gestión del contenedor y de las aplicaciones que contenga.

Dockerextiende LinuX Containers (LXC), un sistema de virtualización ligero que permite crear múltiples sistemas totalmente aislados entre si sobre la misma máquina o sistema anfitrión. No se emula un sistema operativo completo, sólo las librerías y sistemas de archivos necesarios para la utilización de las aplicaciones que tengamos instaladas en cada contenedor.

Debemos tener cuatro conceptos claros:

Imágenes: Una imagen es una captura del estado de un contenedor. Es la preins- talación de aplicaciones a un contenedor. Por ejemplo, una imagen podría conte- ner un sistema operativoUbuntucon un servidor Apache y una aplicación web instalada. Las imágenes se utilizan para crear contenedores, y nunca cambian.

Hay muchas imágenes públicas con elementos básicos como Java,Ubuntuo Apacheque se pueden descargar y utilizar. Normalmente cuando se crean las imágenes, se parte de una imagen padre a la que se le va añadiendo cosas (p.e., una imagen padre conUbuntuy Apache, que se ha modificado para instalar una aplicación).

Las imágenes se identifican por un ID, un nombre y una versión, por ejemplo, ubuntu:latest,django:1.6, etc.

Se ha de tener en cuenta que las imágenes no cambian, si se crea un contenedor a partir de una imagen, y mientras que se está ejecutando el contenedor se cambia algo o se instala alguna herramienta, al parar dicho contenedor y después volver a ejecutar otra vez la misma imagen, esos cambios no se verán reflejados.

Dockerva siguiendo los cambios en los contenedores como si fuera una herra- mienta de control de versiones, por lo que si realmente se desean esos cambios, haciendo uncommitdel contenedor se puede crear otra imagen que contenga dichos cambios.

Por lo tanto, otro beneficio deDockeres el versionado de los contenedores. Si algo va mal en la aplicación, se puede volver de forma sencilla a una versión anterior del contenedor, es decir, a una versión anterior del entorno.

A partir de una única imagen, se pueden ejecutar varios contenedores.

DockerFile: Es un archivo de configuración que se utiliza para crear imágenes.

En dicho archivo indicamos qué es lo que deseamos que tenga la imagen y los distintos comandos para instalar las herramientas.

4

(19)

2.3. Docker Compose

Contenedores: Son instancias en ejecución de una imagen. Son los que ejecutan los servicios. El concepto de contenedor es como si restauráramos una máquina virtual a partir de unsnapshot.

Se podría tener una aplicación ejecutándose en varios contenedores para luego, a través de balanceadores de carga, distribuir los accesos a la aplicación y ofrecer servicios con más garantías y con menos carga de peticiones en cada contenedor.

Volúmenes

No es una buena práctica guardar los datos persistentes dentro de un conte- nedor deDocker. Para eso están los volúmenes, fuera de los contenedores. Así, podremos crear y borrar contenedores sin preocuparnos por que se borren los datos.

Además, los volúmenes se utilizan para compartir datos entre contenedores.

2.3 Docker Compose

Teniendo múltiples contenedores usar el comandodocker runpara cada uno de ellos nos resultará incómodo. En este punto entra Docker Compose[9] permitiéndonos definir nuestra aplicación multicontenedor en un archivo con las mismas propiedades que indicaríamos con el comandodocker runindividualmente.

Con un único comando podremos iniciar todos los contenedores y en el orden que los especifiquemos.

El archivo descriptor nos puede servir no solo como forma de iniciar los contenedo- res en un entorno de desarrollo, sino como monitorización de la aplicación en la que veremos qué contenedores, imágenes, volúmenes, enlaces y demás propiedades tiene asignados.

2.4 Servidor WSGI

Web Server Gateway Interface (WSGI) [10] es unainterfacesimple y universal entre los servidores web y las aplicaciones web oframeworks.

WSGIes similar a la especificaciónJava ServletoASP/ASP.NET. En general, es mucho más simple que dichas especificaciones, y se basa en el estándar Common Gateway Interface (CGI) con mejoras para hacerla reentrante y persistente.

2.5 GIT

Git[11] es un software de control de versiones pensando en la eficiencia y la fiabilidad del mantenimiento de versiones de aplicaciones cuando éstas tienen un gran número de archivos de código fuente.

2.6 Kanvan

Kanban[12] es un método para gestionar el trabajo intelectual, con énfasis en la entrega justo a tiempo, mientras no se sobrecarguen los miembros del equipo. En este enfoque,

(20)

2. CONCEPTOS TECNOLÓGICOS

el proceso, desde la definición de una tarea hasta su entrega al cliente, se muestra para que los participantes lo vean y los miembros del equipo tomen el trabajo de una cola.

2.7 PostgreSQL

PostgreSQL[13] es un sistema de gestión de bases de datos objeto-relacional, distribuido bajo licencia Berkeley Software Distribution (BSD) y con su código fuente disponible libremente. Es una base de datos 100 % Atomicity, Consistency, Isolation and Durability (ACID).

PostgreSQLutiliza un modelo cliente/servidor y usa multiprocesos en vez de mul- tihilos para garantizar la estabilidad del sistema. Un fallo en uno de los procesos no afectará el resto y el sistema continuará funcionando.

2.8 PgAdminIII

PgAdmin[14] es la plataforma de administración y desarrollo de código libre más popular y con más características paraPostgreSQL.

2.9 Django

Django[15] es unframeworkpara aplicaciones web gratuito y de código libre, escrito enPython[16].

Djangoes de los pocosframeworkque con pocas lineas de código viene con un sis- tema de administración activo, listo para ser utilizado sin ningún tipo de configuración.

2.10 NodeJs

Node.js[17] es un entorno de ejecución paraJavaScriptconstruido con el motor de JavaScriptV8 deChrome.

Node.jsusa un modelo de operaciones de E/S sin bloqueo y orientado a eventos.

El gestor de paquetes deNode.js, Node Package Manager (NPM), es el ecosistema más grande de librerías de código abierto en el mundo, siendo así el gestor de paquetes JavascriptdeNode.jspor excelencia.

2.11 Gulp

Gulp.js[18] es un sistema de construcción que permite automatizar tareas comunes de desarrollo, tales como la minimización de códigoJavaScript, recarga del navegador, compresión de imágenes, validación de sintaxis de código...

2.12 Bower

Bower [19] es un gestor paquetes que ayuda a manejar las dependencias de las aplica- ciones y librerías en un proyecto.

6

(21)

2.13. Bootstrap

2.13 Bootstrap

Bootstrap[20] es unframeworkoriginalmente creado porTwitter, que permite crear interfaces web conCSSyJavaScript, cuya particularidad es la de adaptar la interfaz del sitio web al tamaño del dispositivo en que se visualice.

Utiliza un sistema de clases deCSSpara adaptar a cuatro tamaños predefinidos por elframeworkbasados en un sistema de columnas, dividiendo siempre la pantalla en 12 columnas equivalentes.

2.14 Nginx

Nginx[21] es un servidor web/proxyinverso ligero de alto rendimiento y unproxypara protocolos de correo electrónico (Internet Message Access Protocol (IMAP)/Post Office Protocol (POP3)).

Es software libre y de código abierto, licenciado bajo la LicenciaBSDsimplificada;

también existe una versión comercial distribuida bajo el nombre deNginxplus.3 Es multiplataforma, por lo que corre en sistemas tipoUnix(Linux, Solaris, Mac OS X, etc.) yWindows.

2.15 Gunicorn

Gunicorn[22] es un servidor Hypertext Transfer Protocol (HTTP) deWSGI. El servidor Gunicornes ampliamente compatible con una serie de marcos web.

2.16 Memcached

Memcached[23] es un sistema distribuido de propósito general para caché basado en memoria.

Memcachedes empleado para el almacenamiento en caché de datos u objetos en la memoria RAM, reduciendo así las necesidades de acceso a un origen de datos externo (como una base de datos o una Application Programming Interface (API)).Memcached tiene versiones paraLinux, Windows y MacOSy se distribuye bajo licencia de software libre permisiva.

(22)
(23)

C

APÍTULO

3

A RQUITECTURA DE L A APLICACIÓN

En este apartado veremos en profundidad la arquitectura sobre la cual se despliega nuestra aplicación web. Diferenciaremos la arquitectura para desarrollo de la de pro- ducción debido a que para la segunda necesitaremos algunos servicios más que la primera.

3.1 Docker - Docker Compose

3.1.1 Desarrollo

A la hora de construir nuestra web hemos montado todo para que desarrollemos y despleguemos el aplicativo a través de múltiples contenedoresDocker, los cuales manejaremos y ejecutaremos a través deDocker Compose.

Como muestra el esquema de la figura3.1llamaremos a tres contenedores que instalarán todas las dependencias necesarias para poder comenzar a desplegar el aplica- tivo. Se debe remarcar que los tres contenedores tienen una dependencia programada con otro contenedor que despliegaNode.js.

Cuando ejecutemos cualquiera de los tres contenedores mencionados anterior- mente, antes de nada, resolverá la ejecución de un contenedor que instala la imagen deNode.jsen el contenedor lanzado.

El primer contenedor será el que contiene el gestor de paquetesNPMdeNodejs, necesario para la instalación de los dos siguientes contenedores. El segundo conten- drá el gestor de libreríasBowery el tercero el sistema de construcciónGulp, que nos permitirá la automatización de tareas y procesos que más adelante trataremos.

Estos contenedores solo tienen la finalidad de instalar dependencias, por tanto, una vez instaladas desaparecerán, pero al montar todo sobre el volumen.:/opt/de nuestra máquina, un directorio estático y compartible, nos permitirá que el contenedor de la web pueda acceder a las aplicaciones deNode.jsinstaladas.

Toda la tarea de lanzar estos tres contenedores ha sido automatizada a través de un Makefileque con un comando nos ejecutará las tres instalaciones.

(24)

3. ARQUITECTURA DE LA APLICACIÓN

Figura 3.1: Contenedores con Bower, Gulp y Npm dependientes del contenedor Node.js.

Ahora pasaremos a ver cómo desplegar el entorno de nuestra aplicación web3.2.

Lo haremos a través de un contenedorDocker, el cual llamaremosdev, que construye una imagen que parte de laImageFieldoficial dePython:3.4, la cual se encuentra en el repositorio de imágenes de Docker (Docker Hub).

Figura 3.2: Interacción entre el desarrollador, el contenedordevy la base de datos.

Este contenedor lo primero que ejecuta es la construcción de la imagen dePython a través del comandobuild.

Cuando construimos la imagen entramos dentro del archivoDockerfiledonde se le especifica, la actualización de los paquetes deLinux, la eliminación de archivos temporales en el directorio/temp, la instalación del cliente dePostgres, para conectar con la base de datos, y la instalación de los requerimientos, especificados en el archivo requeriments.txt, a través del administrador de paquetes dePython(pip).

10

(25)

3.1. Docker - Docker Compose

Dentro del archivo de requerimientos se especifican las siguientes aplicaciones:

Django:frameworkpara aplicaciones web gratuito y de código libre, escrito en Python, el cual utilizaremos para montar toda nuestra web.

Django Rest Framework: aplicaciónDjangoque permite construir proyectos software bajo la arquitectura REST, incluye una interfaz administrativa desde la cual es posible realizar pruebas sobre las operacionesHTTPcomo lo son:POST yGET.

Psycopg2: adaptador, requerido porDjango, de la base de datosPostgreSQLpara el lenguaje de programaciónPython.

Python-decouple: librería que ayuda a separar estrictamente los parámetros de configuración del código fuente. Los parámetros relacionados con el proyecto van directamente al código fuente y los parámetros relacionados con una instancia del proyecto van a un archivo de entorno.

Gunicorn: también conocido comoGreen Unicorn, es un servidorWSGIHTTP paraPython. Sólo lo utilizaremos en producción, lo explicaremos más adelante dentro del apartado de despliegue del aplicativo en producción.

Pillow: librería gratuita que permite la edición de imágenes directamente desde Python. Soporta una variedad de formatos, incluidos los más utilizados como Graphics Interchange Format (GIF), Joint Photographic Experts Group (JPEG) y Portable Network Graphics (PNG).

Ipdb: librería que exporta funciones para acceder al depurador deIPython, que incluye la finalización de tabulaciones, resaltado de sintaxis, mejores trazados y mejor introspección con la misma interfaz que el móduloPython Debugger[24].

Requests: librería dePythonque permite enviar solicitudesHTTP/ 1.1. De es- ta manera no es necesario agregar manualmente las cadenas de consulta a las Uniform Resource Locator (URL) ni codificar formalmente los datos POST. Las conexionesHTTPson 100 % automáticas, gracias a la librería dePython3preins- taladaurllib3[25].

Social-auth-app-django: librería que tiene como objetivo ser un mecanismo de autenticación y autorización social fácil de configurar para proyectosPythonque soporten protocolosOAuth[26] (1 y 2) yOpenId[27].

Python-memcached: Interfaz dePythonpara el demonio de la memoria caché memcached. Es un software situado en lado del cliente que permite almacenar valores en uno o más servidores.

A continuación, pasamos a definir las variables de entorno de nuestro contenedor, las cuales nos servirán para definir el nombre de la base de datos, el puerto, elhost, el usuario y la contraseña con la que debe conectarseDjangoa través del archivo de configuración.

(26)

3. ARQUITECTURA DE LA APLICACIÓN

Ejecutaremos toda la web en el volumen.:/opt/appy a través de la opción-links permitiremos a los contenedores descubrirse mutuamente y transferir con seguridad la información entre ellos. Es decir, se creará un conducto entre el contenedor de origen weby el contenedor destinatariodb, el cual contiene la base de datos. Así, el destinatario puede entonces acceder a datos sobre el origen.

Los enlaces también expresan la dependencia entre los servicios de la misma manera quedepends_on, por lo que determinan el orden de inicio del servicio. Así, el contenedor de la base de datos llamadodbdeberá lanzarse antes que la ejecución del contenedorweb.

El contenedordbse montará sobre una imagen oficial dePostgres:9.5.1situada también en el repositorio de imágenes deDocker. A este contenedor se le especificará que esté expuesto el puerto"5432"y que esté montado sobre el volumen/opt/<name- aplication>/postgresql:/var/lib/postgresql/data". Además se le especificarán unas varia- bles de entorno con los principales datos de configuración dePostgres.

A continuación desplegamos el contenedorMencachedbasado en la imagen ofi- cialMemcached:1.4.36. Este contenedor nos permitirá cachear nuestro sitio web y manejarlo desde un contenedor individual a través del puerto"11211". Esta enlazado directamente con el contenedorweby se instalará después del contenedor de la base de datos.

Una vez desplegados todos los contenedores anteriormente descritos podemos trabajar en la zona de desarrollo ya sea en local o en un servidor remoto. A partir de este punto se podría pensar que falta desplegar un servidor web para poder hacer correr nuestra web, pero para ello ya tenemos aDjango.

Djangoincluye un servidor Web ligero [28] (que es llamado con el comandorunserver) que puedes usar mientras estás programando nuevas funcionalidades. Este servidor permite desarrollar de manera rápida, sin tener que lidiar con configuraciones de servidores Web para producción (por ejemplo,Apache) hasta que se esté listo para producción.

Este servidor de desarrollo vigila el código a la espera de modificaciones y se reinicia automáticamente, ayudando a hacer cambios rápidos en el proyecto sin necesidad de reiniciar ningún servicio.

Así, en el siguiente apartado trataremos como desplegar nuestro aplicativo en producción, teniendo que levantar un servidorWSGIpara servir nuestra aplicación dinámica y otro servidor para manejar los estáticos.

3.1.2 Producción

Para la instalación de nuestro entorno en producción seguiremos el esquema de la figura3.3.

Para producción utilizaremos los mismos contenedores que hemos usado en desa- rrollo, pero además levantaremos otros dos contenedores extra, uno que contendrá Gunicorny otroNginx.

El contenedor deGunicornejecutará el servidor web que servirá en producción todo el contenido dinámico y es quien se encargará de interactuar con la base de datos del contenedor que contienePotgreSQLy además tendrá expuesto el puerto 8888.

Para poder mantener los datos fuera del contenedor se direccionarán a la ruta

".:/opt/app"del servidor.

12

(27)

3.2. Diagrama de la arquitectura

Figura 3.3: Sistema desplegado en producción a través de contenedoresDocker.

El contenedor deNginxse montará a partir de una imagen deDockeroficial de Nginxen su versión 1.9. Redirigiremos los datos fuera del contenedor a la carpeta específica"./dockerfile_nginx/nginx.conf:/etc/nginx/nginx.conf"donde encontramos toda la configuración del servidor web. Además, asignaremos el puerto 80 de nuestro servidor como entrada al contenedor.

En producción todos estos contenedores se desplegarán conDockersobre el sis- tema operativoDebian8 (Jessie) el cual estará corriendo en un Servidor Privado Vir- tual (VPS) externo.

3.2 Diagrama de la arquitectura

En esta sección podemos ver el diagrama3.4que muestra la arquitectura general de la web y las relaciones bidireccionales que tienen los componentes. El diagrama parte de las peticiones del cliente a través de un navegador, el cual primero se conectará a través del puerto 80 con el servidorNginx. Este analizará si la petición requiere servir algún tipo de fichero estático, como por ejemplo, imágenes estáticas o ficheros de estilos, que no se encuentren cacheados dentro del navegador y se encargará de servirlo al cliente directamente sin tener que hacer una petición al servidor de la aplicación para cargar contenido estático.

A continuación, si la petición del cliente necesita servir algún archivo el cual requie- re un acceso a la base de datos o acceso a los archivos delframeworkse conectará al servidor deGunicornel cual sirve la aplicación deDjangoy permitirá gestionar todas las peticiones dinámicas de los clientes.

Para queGunicornpueda interactuar con elframework Djangose debe conectar a través delMod_WSGI. Este conector es una interface dePythonque permite interactuar nuestro proyecto con el servidor deGunicorn.

(28)

3. ARQUITECTURA DE LA APLICACIÓN

Si se requiere una llamada a la base de datos para insertar, modificar o eliminar alguno de los datos contenidos en ella se deberá realizar a través del modeloMVCde Django, el cual se conectará a la base de datos dePostgreSQLy realizará las acciones necesarias sobre ella.

Para la web deTinta y Pielutilizamos el entorno de ejecución deJavascript NodeJs el cual nos permitirá manejar a través de su gestor de paquetesNPMmúltiples depen- dencias, como el gestor de paquetesBower, la herramienta de automatización de tareas Gulpo la extensión deCSS Less.

En el proyecto se utilizan muchas librerías de terceros. Para gestionar su descarga y su posterior mantenimiento utilizamosBowerquien, a través de un pequeño archivo de configuración, permite establecer las dependencias y las versiones que se deben descargar de los repositorios. A continuación, se utilizaGulppara minimizar, mapear y versionar los archivos estáticos y para comprimir las imágenes.

Además, se utiliza la herramientaCompressor[29] para realizar una compresión de todos los archivos deJavascriptyCSSminimizados y revisarlos para que el navegador detecte si debe volverlos a cachear porque han sufrido algún tipo de modificación.

Por otro lado tenemos la autenticación de los usuarios con laAPIdeInstagramque se conectará con la web a través del protocoloOAuth 2.0, el cual mediante unTokeny el registro del cliente nos autenticará para poder recibir información de laAPI.

Por último, para gestionar la cache de la web, utilizamos la herramientaMemca- chedque nos permite a través delcore[30] deDjangocachear progresivamente en el navegador del cliente todo el sitio web a medida que va navegando por él.

Una vez cacheado el sitio webMemcachedgestiona de manera automática la com- probación de si los archivos cacheados han sufrido algún tipo de modificación y deben volverse a servir y ser nuevamente cacheados.

3.3 Arquitectura dentro del Framework Django

En esta sección trataremos la arquitectura propia en la que se ha organizado elFra- mework Djangopara nuestra web. Para la organización interna del proyecto se han distinguido dos aplicaiones. La primera es la web, donde en una misma carpeta con- tendremos a través de subdirectorios las vistas, las configuraciones de lasURL, las plantillas deHTML, los controles y validaciones de los formularios, la configuración delSitemapde la web y los archivos de testeo.

En la aplicaciónAPIse tiene el modelo de la web con todas las clases de la base de datos escritas enPython. Además contiene las migraciones con los cambios que se realizan sobre el modelo para que se puedan aplicar correctamente sobre la base de datos a través del comandomake makemigratiosymake migrate.

El directorioAPItambién va a contener una carpetamanagementdonde almace- naremos todos los comandos que interactúen con la base de datos. Por ejemplo, el comando para borrar y precargar la base de datos con usuarios de test o el comando para introducir todas las provincias y municipios de España o las posibles categorías de los tatuajes.

Al mismo tiempo, dentro de este directorio tendremos el fichero de configuración del administrador deDjango, lo localizamos en esta carpeta debido a que se encargará de definir las clases del modelo a las que podremos tener acceso en el administrador, y 14

(29)

3.3. Arquitectura dentro delFramework Django

Figura 3.4: Diagrama general de la arquitectura de la web y las conexiones bidirecciona- les pertinentes.

especificar qué permisos y acciones estarán disponibles dentro del panel de control para cada clase.

La carpetadataincluye todos los archivosJSONque son necesarios para cargar información en la base de datos, por ejemplo, las provincias y los municipios con sus correspondientes nombres, latitudes, longitudes y códigos postales.

Todas las configuraciones de las imágenes deDocker,Docker Composey de los archivos de configuración deGulp,Bower,NPMypipsiempre se encuentran en el directorio principal del proyecto exceptuando la imagen deNignxy su configuración, situada en la carpetadockerfile_nginx.

La configuración del proyecto deDjangose encuentra situada en la carpetata- tuados, en el directorio principal. Este directorio contiene la carpetamedia, con todo el contenido multimedia de la web que debe ser referenciado por la base de datos, y la carpetastatic, con todo los ficheros estático de la web como imágenes, estilos, javascript... También se encuentra la carpetastaticfieldsque indica dondeDjangodebe buscar los archivos estáticos adicionales.

Además, encontremos los dos archivos de configuración principales deDjango, settings.pyysettings_develop.py. El primero se utiliza para el entorno de producción, mientras que el segundo para el entorno de desarrollo. En estos archivos se encuentran las claves de conexión con lasAPI, las configuraciones de loslogs, la definición de las rutas de los estáticos, la codificación del lenguaje y el horario por defecto de la aplicación.

(30)

3. ARQUITECTURA DE LA APLICACIÓN

En el directoriotatuadostambién podemos encontrar la configuración de lospi- peline[31] que se ejecutan en la autenticación de la web por medio de redes sociales, a través de la libreríasocial-auth-app-django[32] y el archivo de configuración de la interfaceWSGIpara la conexión con el servidor deGunicorn.

Por último, la carpetataskscontiene losscriptsque se utilizan como apoyo adi- cional a la hora del desarrollo de la web. Como, por ejemplo, elscript que detiene todos los contenedoresDockerdel sistema, parados o activos, y los elimina. Este tipo de ejecuciones aceleran el proceso de desarrollo automatizando tareas a la hora de programar.

16

(31)

C

APÍTULO

4

B ASE DE DATOS

La base de datos es uno de nuestros pilares en el aplicativo y el negocio, puesto que forma parte delcore bussinessde Tinta y Piel.

Se comenzó el proyecto utilizandoSQLite3[33] como base de datos para desarrollo por su simpleza en la configuración yPostgreSQLcomo base de datos para producción, pero a lo largo de 2 meses y estudio de buenas prácticas deDjango[34] y su despliegue se optó por migrar la base de datos de desarrollo aPostgreSQLtambién.

De esta manera, trabajamos en un mismo entorno en el que las pruebas que se hagan en el desarrollo de nuevas funcionalidades en local pueden acercarse más a las del servidor y acotar el número de errores referentes a la base de datos.

Además al tener la misma tecnología en desarrollo y producción nos ahorramos las diferentes configuraciones que deberían darse para cada base de datos si utilizásemos tecnologías diferentes.

4.1 Modelo UML

ElUMLde la webTinta y Pielqueda reflejado en la figura4.1donde se exponen las clases que tendrá la base de datos y algunos atributos que se han considerado de especial relevancia.

4.2 Clases y relaciones

4.2.1 Geolocalización del usuario

Las clasesCountry, Province, CityyPostalCodenos sirven para poder tener un control sobre el usuario y su localización, de esta manera podemos categorizar los profesionales por ciudades y provincias de manera que la búsqueda principal de los usuarios que buscan tatuadores sea a través de la localización.

Además localizar geográficamente a los usuarios permite monitorizar los índices de actividad por zonas y focalizar las campañas de marketing.

(32)

4. BASE DE DATOS

Figura 4.1: ModeloUMLde la base de datos de Tinta y Piel.

Las clasesProfessional, MyUser, ProfessionalProfileyMyUserProfilenos permi- ten extender la claseUserdeDjangoy tener un control del usuario, incluyendo todo el histórico de usuarios y el login.

El objeto deDjango User proveé cinco atributos básicos (nombre de ususario, primer nombre, segundo nombre, email y password) y varias funciones para controlar la autenticación del usuario de manera fácil.

Un usuarioProfessionalse distingue principalmente de unMyUseren que elPro- 18

(33)

4.3. PotgreSQL

fessionaltendrá una dirección, un teléfono, una puntuación de feedback y un perfil público que podrá visitar cualquier persona.

Las clasesOpinion, Comment, OpinionPhoto, UsefulOpinionyUsefulComment nos sirven para poder tener un sistema completo de opiniones y comentarios sobre los profesionales y las fotos, que a su vez, pueden ser valorados por otros usuarios como útiles.

Estos útiles sirven para obtener unfeedbackcontinuo sobre las opiniones y los comentarios que los usuarios realicen sobre los profesionales del sector del tatuaje.

Todos ellos vienen con untimestampy asignados a un usuario perteneciente a la base de datos.

Las opiniones a profesionales sólo podrán ser realizadas por usuarios (MyUser) pero los comentarios estarán permitidos tanto a los usuarios profesionales como a los que no lo son. Los usuarios no registrados sólo podrán visualizar las opiniones y comentarios del profesional pero no podrán realizar ninguna acción para interactuar con ellos.

Las clasesProfessionalPhoto, TattoPhoto, OtherPhoto, ProfessionalFolder, Cate- gory, ColoryBodynos registran en la base de datos las rutas de acceso a todas las fotos de los profesionales y permiten la categorización, en caso de ser un tatuaje, de esa foto.

Las fotos no se guardan en la base de datos, se almacenan en la carpetamediadel directoriotatuadosy en la base de datos se almacena la dirección de estas para poder servirlas directamente.

De esta manera, creamos una indexación desde la base de datos a la ruta que contiene los archivos de imágenes mejorando el rendimiento de la sentenciaqueryen un 50 % [35].

La claseMedalnos permitirá en un futuro otorgar premios y recompensas en forma de insignias a los profesionales mejor valorados. Este tipo de medallas favorecerán el feedbackque tiene el profesional en la web y le animará a continuar usándola para poder obtener más insignias.

Las clasesQuestionProfyAnswerProfnos sirven para tener un control de posibles cuestionarios que presentar a los profesionales con la finalidad de hacer estadísticas internas. Estos cuestionarios están pensados para ponerse al final de la subida de una foto y así poder sacar mejores métricas para evaluar la calidad de la web.

Las clasesRate. PayyBillpermiten establecer un sistema de pago para los profe- sionales que deseen determinados servicios que les posicione mejor en las búsquedas internas de nuestro buscador. Estas clases básicamente almacenan datos bancarios de los pagos realizados, pero no sustituyen una pasarela de pago, para ello se utilizaría un Terminal Punto de Venta (TPV) virtual.

Cabe destacar que todas las clases contienen siempre los atributoscreated_aty updated_atpara tener en el administrador unlogde la creación y modificación de los objetos. Además contienen un identificador único que auto genera la base de datos cuando crea los objetos de cada clase.

4.3 PotgreSQL

Nuestra aplicación usa la versión 9.5.1 dePostgreSQLy se encuentra corriendo sobre un contenedorDockeren el mismo servidor donde esta el aplicativo web, conectándolos a

(34)

4. BASE DE DATOS

través del puerto 5432.

Para poder utilizarPostgreSQLcon elFramework Djangoutilizamos el módulo de Python django.db.backends.postgresql_psycopg2que nos permite utilizar los modelos deDjangoy conectarlos a la base de datos para hacer migraciones.

El arranque de la base de datos, a través del contenedorDocker, está automatizado con el levantamiento del contenedorweba través del atributolinken la imagen de docker-compose, es decir, cuando levantamos el contenedor de la web, automática- mente primero se levanta la base de datos, sin tener que hacer nada nosotros. Esto nos permite despreocuparnos en los despliegues de que algún contenedor quede sin arrancar.

En caso de que se requiera acceder al contenedor donde se encuentra la base de datos deberemos llamar al comandomake connect-db. Esto nos permitirá entrar dentro del contenedor y acceder a las funcionalidades propias dePosgreSQL.

4.4 PgAdminIII

A través de esta aplicación de código abierto podremos conectarnos remotamente, mediante una interfaz gráfica, a nuestra base de datos a través del puerto"5432". De esta manera, podemos controlar las tablas de la base de datos a un nivel muy detallado y con una interacción gráfica.

Además nos permite realizar consultas Structured Query Language (SQL) directa- mente sobre la base de datos, controlar las vistas, realizartrigguersy aplicar filtros sobre las tablas para poder hacer búsquedas rápidas y dinámicas. En la web deTinta y Piella utilizamos principalmente para realizar losbackupsperiódicos de la base de datos. Ac- tualmente se hacen manualmente a través de la propia aplicación. La automatización de estosbackupsse encuentra aún en fase de desarrollo.

Se tiene previsto en un futuro implementar la automatización de las copias de seguridad, a través deCron, el cual nos permitirá regular los procesos en segundo plano que queramos lanzar cada período de tiempo.

20

(35)

C

APÍTULO

5

B ACKEND

En elbackendde nuestra web utilizamos elFramework Djangoen su versión 1.11 para desarrollar casi todas las funcionalidades. Hemos escogifo esteFrameworkpor su simpleza a la hora de programar conPython, por la gran comunidad de código libre que tiene detrás y por la facilidad que ofrece para montar un sistema de administración completo sobre las clases de la base de datos.

5.1 NodeJS

Para empezar, nuestro proyecto necesita el entorno de ejecuciónNode.jspara poder utilizar su gestor de paquetes y poder descargar las dependencias definidas en el archivo package.json.

Su instalación se realiza a través deDockeren los contenedoresNPM,BoweryGulp que permitirán crear las conexiones al volumennode_modulesdonde se encuentran todas la librerías descargadas a través de este entorno de ejecución.

El directorionode_modulesesta incluido en el archivo.gitignorepara evitar subir todas las dependencias al repositorio, de manera que al iniciar el proyecto o a la hora de hacer el despliegue es necesario instalarlas en la máquina donde va a correr la web a través del comandomake install.

Por tanto, a la hora de desarrollar las dependencias generadas porNodejssólo deben estar presente en el directorio de trabajo de cada programador.

5.2 Gulp

UtilizaremosGulppara diferentes automatizaciones en nuestra web. La primera es para poder agrupar todos nuestros archivos.lessen un sólo archivomain.less, después recompilaremos este archivo enCSSy lo minimizaremos en un archivo.min.css.

(36)

5. BACKEND

La segunda automatización realizada es para agrupar y minimizar todos los archivos javascript, tanto propios como de librerías importadas conbower, en un sólo archivo main.min.js.

Todas estas acciones están programadas para realizarse cada vez que se modifica un archivo.lesso.js. Esto lo podremos llevar a cabo gracias a la función degulp watch(), la cual nos permite estar escuchando los cambios en los archivos especificados en la propia función.

Gulpsolo estará pendiente de los cambios si lanzamos la funciónwatch()a través del comandomake gulp-watchy solo la utilizaremos en el entorno de desarrollo para poder trabajar de manera más cómoda.

A través de la siguiente función, ejecutamos la escucha de los archivosJavascripty Lesscada vez que lancemos el comandowatch.

gulp . task ( ’ watch ’ , function ( ) { // main task

gulp . watch ( paths . s c r i p t s , [ ’ s c r i p t s ’ ] ) ; gulp . watch ( paths . l e s s , [ ’ l e s s ’ ] ) ;

} ) ;

En cambio, para el entorno de producción a la hora de recompilar los estáticos y realizar de manera automática todas estas tareas descritas anteriormente deberemos lanzar el comandomake collectstaticque nos lanzará la funcióndefaultdegulpdonde tenemos descritas las tareas anteriormente expuestas delessyjavascripty además una tarea para redireccionar los archivos donde se encuentran las fuentes de la librería font-awesomey otra para minimizar todas las imágenes estáticas.

Además, tenemos implementada la librería dePython django_compressorque nos permite procesar, combinar y minimizarJavaScript, vinculado o en línea, yCSSen archivos estáticos en caché. Esta librería también nos renombra estos archivos estáticos añadiendo unhashal final del nombre para que el navegador detecte que ha habido cambios en los archivos y que debe volver a cachearlos.

De esta manera evitamos que los usuarios tengan que refrescar la cache para poder visualizar los cambios en los estilos y en elJavascript.Django-compressorsólo lo utilizaremos en producción ya que para desarrollo no necesitaremos minimizar los archivos ni aplicarles el proceso de renombrarlos.

5.3 Django

Nuestro proyecto se basa en tres tipos de aplicaciones:

Aplicaciones propias deDjango: Para hacer el desarrollo más ágil aprovechamos diferentes aplicaciones ya realizadas por el propioframeworkcomo:

La autorización del usuario[36]Djangoproporciona una clase de usuario, User, ya predeterminada con todas las funciones de autenticación incorporadas y con los principales atributos de un usuario como el nombre de usuario, el nombre completo, una contraseña y el correo electrónico.

Además esta clase nos permitirá implementar un sistema de recuperación de contraseñas seguro y con validación mediantetokensenviados por correo elec- trónico.

22

(37)

5.3. Django

Esta aplicación incorpora algunas rutas (URL) para el inicio y cierre de sesión y para el proceso de recuperación de la contraseña que se deberán especificar en el archivo de enrutamientoweb/urls.py.

El panel de administración[37]Djangoproporciona la interfaz de adminis- tración de manera casi automática con las principales funcionalidades como crear, editar o eliminar cualquier objeto de la base de datos.

Todas las rutas de administración partirán del sufijo/admin/y deberán ser auten- ticadas como usuario con el rolstaff.

El seguimiento de todos los modelos:[38]Djangoincluye una aplicación contenttypesque puede realizar un seguimiento de todos los modelos instalados en el proyecto, proporcionando una interfaz genérica de alto nivel para trabajar con los modelos.

Las variables de sesión:[39]Djangoproporciona soporte completo para sesiones anónimas. Permite almacenar y recuperar datos arbitrarios por visitante.

Almacena datos en el lado del servidor y abstrae el envío y recepción decookies.

Este tipo de variables las utilizaremos especialmente para guardar losTokensde autenticación cuando los usuarios quieran conectarse a su cuenta deInstagram y la aplicación deba autenticarse frente laAPIde esta.

Los mensajes:[40]Djangoproporciona soporte completo para la mensa- jería basada encookiesy en sesiones, tanto para usuarios anónimos como au- tenticados. Nos permite almacenar temporalmente mensajes en una solicitud y recuperarlos para su visualización en una solicitud posterior.

Cada mensaje está etiquetado con un nivel específico que determina su prioridad (por ejemplo, información, advertencia o error).

Aplicaciones nuestras:Aplicaciones propias, desarrolladas por nosotros.

Api:contiene el modelo con las clases que forman la base de datos. Todas las rutasURLtendrán el sufijo/api/para diferenciar las llamadas al modelo de las llamadas a rutas de la web.

Web:contiene las vistas y las plantillas de nuestra aplicación, es decir, tiene el controlador de la web que selecciona qué datos se deben obtener y cómo mostrarlos en las plantillas.

Aplicaciones desarrolladas por terceros:

rest_framework: permite construir proyectos software bajo la arquitectura Representational State Transfer (REST). Proporciona una interfaz administrativa desde la cual es posible realizar pruebas sobre las operacionesHTTP. Actualmen- te se encuentra en fase de desarrollo, se pretende migrar todas las vistas posibles a unaAPIde arquitecturaRESTcreada con esteframework.

rest_framework.authtoken: provee aDjangolas migraciones necesarias deRest_Framworkpara la base de datos.

(38)

5. BACKEND

5.3.1 MVP (Modelo-Vista-Plantilla)

Nuestra aplicación se basa en una arquitectura Modelo Vista Controlador (MVC) [41], peroDjangotiene su propia nomenclatura para este tipo de arquitectura.[42]

Un modelo deDjangoes una descripción de los datos en la base de datos, represen- tada como código dePython. El modelo es nuestra capa de datos — lo equivalente a la sentenciaSQL CREATE TABLE— excepto que están enPythonen vez deSQL.

Permite la creación de clases y la asignación de atributos a estas a un alto nivel.

Djangousa un modelo para ejecutar códigoSQLpor detrás y retornar estructuras de datos convenientes enPythonrepresentando las filas de las tablas de la base de datos.Djangotambién usa modelos para representar conceptos de alto nivel que no necesariamente pueden ser manejados porSQL.

De esta manera en los controladores a través de llamadas a las clases definidas en los modelos de la aplicaciónapiobtenemos objetosPythonque podemos utilizar directamente en las plantillas a través del lenguajeDjango-Template.

Por ejemplo:

pro = P r o f e s s i o n a l . obj e cts . p r e f e t c h _ r e l a t e d ( ’ p r o f _ f o l d e r ’ ) . get ( pk=prof_id ) Esta función nos permite acceder a todos los objetos de la tablaProfessionaly se-

leccionar los que tienen unaidequivalente aprof_id. De esta manera con una pequeña sentencia enPythongeneramos la llamada a la base de datos y retornamos un objeto de la claseProfessionalcon sus atributos y, en este caso, precargado también el objeto prof_folder, el cual es clave foránea de un profesional.

Por otro lado, una “vista” en nuestra aplicación es la función decallbackenPython para unaURLen particular, así esta funcióncallbackdescribe que dato es presentado.

Pero nuestras vistas nunca representan ningún dato, siempre lo ceden, a través de un contexto, a una plantilla la cual describe cómo se presenta el dato.

Las plantillas están alojadas en la aplicaciónwebdentro del directoriotemplates/.

Son los archivosHTMLque contienen la parte gráfica donde se mostrarán los datos seleccionados en la vista. Estos datos los representaremos a través del lenguaje de plantillasDjango-templateque nos permitirá acceder a los atributos de los objetos directamente.

Dentro del directoriotemplatesencontraremos el subdirectoriocomponentscon diversos archivosHTML. Estos archivos han sido separados para poder organizar mejor el código y evitar repetir fragmentos iguales más de una vez. De esta manera, a través de unimportpodremos importar el componente y tener un código más limpio.

5.3.2 Desacoplamiento de las variables sensibles

Para aplicar más seguridad en nuestra web desacoplaremos de nuestro proyecto todas las variables con información sensible. Así evitaremos que si el repositorio es compro- metido por un ataque o por alguna vulnerabilidad del personal podamos evitar exponer este tipo de información.

Para este cometido utilizamos la libreríapython decouple 3.0[43] que nos permite definir un archivo.envel cual contendrá todos los datos sensibles y el cual se añade en el.gitignorepara evitar que el repositorio lo contemple.

24

(39)

5.4. Logs

Estas variables se convertirán en variables de entorno las cuales quedarán en el sistema y no se modificarán hasta que se modifique el archivo.envy se reconstruya la imagen deDocker.

Así veremos, por ejemplo, la contraseña del correo electrónico dentro de nuestro archivo de configuración deDjango(settings.py)

EMAIL\_HOST\_PASSWORD = config ( \ t e x t i t { "EMAIL\_HOST\_PASSWORD" } )

5.4 Logs

Djangonos permite implementar de una manera sencilla un sistema para controlar los errores de la web y registrarlos en un archivo o enviar un correo a un administrador de la aplicación para que tome las medidas oportunas.

En el caso deTinta y Pielse ha optado por la segunda opción. Todos los errores internos de la web son enviados al correo corporativocarlos.tenorio@tintaypiel.es. Esto lo definimos en el archivosettings.pyde la siguiente manera:

# Error r e p o r t i n g

ADMINS = [ ( ’ Carlos ’ , ’ c a r l o s . t e n o r i o @ t i n t a y p i e l . es ’ ) ]

Los errores llegan en modoDEBUGincluyendo el tipo de error, la linea de código donde ha fallado y posibles acciones correctivas para solucionar el problema.

Para los errores internos dentro de los contenedoresDockerutilizamos el propio sistema de reporte deDockera través del comando:

docker logs nombre_del_contenedor

Esto nos imprimirá a través de la consola los últimos reportes registrados por el contenedor y si ha habido algún fallo interno lo especificará y describirá el tipo de excepción producida.

5.5 Integración de la API de Instagram

5.5.1 Introducción

En nuestro proyecto utilizamos laAPIdeInstagrampara poder hacer el registro y el inicio de sesión a través de nuestra cuenta deInstagramy para que los usuarios puedan subir fotos directamente desde su cuenta deInstagram.

Se ha elegido esta red social porque la mayor parte de los tatuadores tienen cuenta en ella donde suben todos sus trabajos. De esta manera, se facilita que se suban las fotos de una manera fácil y cómoda.

5.5.2 Permisos

Para poder acceder a la información del perfil de un usuario y a sus fotos más recientes Instagramnos ha tenido que autorizar previamente a poder recibir los permisos básicos para autenticar a los usuarios y poder acceder a su contenido multimedia más reciente.

Los permisos solicitados y posteriormente aprobados son los básicos que nos permiten leer la información y el contenido multimedia de los perfiles de los usuarios.

(40)

5. BACKEND

Para la aprobación de los permisos por parte deInstagramse ha presentado un vídeo explicativo1donde se muestra la experiencia de inicio de sesión en la red social dentro deTinta y Piely el uso de cada permiso que se está solicitando. También se han tenido que integrar las políticas de privacidad dentro de losTérminos y condiciones de usode la web, los cuales se pueden encontrar de manera pública en la dirección2.

Mientras se esperaban los permisos, para desarrollar la integración con laAPIse habilitó un modoSandboxque permitía hasta 5 usuarios con todos los permisos.

5.5.3 Social-Auth y acceso al contenido multimedia

Para la autenticación, tanto en el registro como en el inicio de sesión, utilizaremos un módulo externo deDjangollamadosocial-auth-app-django. Este nos permitirá, a través del módulosocial-auth-corellamar a laAPIdeInstagramy recibir la información básica de su perfil junto a un token único.

Para realizar el proceso de autenticación frente a laAPIde la red social utilizaremos las siguientesURL:

1) u r l ( r ’ ^signup_instagram /$ ’ ) , 3) u r l ( r ’ ^signup_instagram_pro /$ ’ ) ,

4) u r l ( r ’ ^signup_instagram_pro_success /$ ’ ) , 2) u r l ( r ’ ^pro/ api_instagram /$ ’ ) ,

La primera nos mostrará una pantalla5.1donde deberemos elegir si somos o no pro- fesionales. Al pulsar en una de las dos opciones nos redirigirá a laURL login/instagram, la cual pertenece a la libreríasocial-auth-app-djangoy que nos permite autenticar directamente al usuario y redirigirlo a la direcciónsignup_instagram_propara poder completar el formulario de registro5.2de la web. Hay que destacar que el usuario una vez que llegue a ese formulario ya estará registrado en la base de datos como usuario profesional o no, solo que se le solicitaran algunos campos extras en caso de ser tatuador para poder completar su perfil.

Una vez completado el formulario nos redirigirá a la cuartaURLdonde accedere- mos al perfil ya creado, como muestra la figura5.3.

Figura 5.1: Elección si eres tatuador o no en la URL signup_instagram .

La cuartaURLse utiliza cuando el usuario desea subir fotos de su cuenta en la red social directamente a su perfil enTinta y Piel, de esta manera autenticamos al usuario deInstagrama través de una llamada a la siguienteURL, la cual se activará al pulsar el botón de’subir fotos desde Instagram’

1https://www.youtube.com/edit?o=Uvideo_id=U3Q1KMJ8Gqk 2http://www.tintaypiel.es/terms

26

(41)

5.5. Integración de la API deInstagram

Figura 5.2: Formulario para los profesionales una vez autenticados con su cuenta de Instagram.

Figura 5.3: Perfil de un profesional recién registrado a través de su cuenta de Instagram

Esta llamada nos devolverá en laURLun código que deberemos pasar por pará- metro a la llamada de adquisición del Token de laAPI,con el cual realizar llamadas autenticadas.

Deberemos pasar la siguiente información para que laAPIautentique el usuario a través del cliente autorizado (tinta_y_piel_comparador) y le permita devolvernos el token necesario para hacer cualquier llamada a laAPI.

(42)

5. BACKEND

client_id: número de identificador único de la cuenta deInstagramque tiene autorizado los permisos para acceder al contenido básico del perfil del usuario que intenta autenticarse.

client_secret:número secreto del cliente autorizado para las llamadas a laAPI

grant_type: a través del valorauthorization_codele indicaremos que en la llama- da está incluido un código, previamente recogido, para poder acceder al token.

redirect_uri: indica la dirección a la que laAPIdebe dirigirse después de la llamada. Esta dirección debe ser previamente configurada en la cuenta del cliente (tinta_y_piel_comparadodeInstagram.

code: código de autenticación que recibimos en la primera llamada al pulsar el botón de subir y el cual nos sirve para recibir el Token.

Para poder obtener las fotos más recientes de la cuenta de un usuario enInstagram no utilizamos el token recibido por el módulosocial-auth-app-djangodebido a que la subida de fotos desdeInstagramdebe facilitarse a todos los profesionales, no sólo a los autenticados desdeInstagram.

Por tanto, cuando cualquier profesional presione en el botón de subir fotos desde Instagramse hace una llamada a la siguienteURL:

https : / / api . instagram .com/v1/ users / s e l f /media/ recent / ? access_token A continuación la web nos redirigirá a una página5.4donde podremos seleccionar las fotos que queramos subir y colgarlas directamente en nuestro perfil. Por defecto las fotos las asociará al último álbum creado por el usuario.

Figura 5.4: Selección de las fotos más recientes de la cuenta de Instagram que se desean subir a la web

28

(43)

5.5. Integración de la API deInstagram 5.5.4 Pipelines

El módulosocial-auth-app-djangonos permite utilizar un mecanismo extensible de pipelinesdonde podemos introducir funciones paralelas durante el proceso de autenti- cación.

Lospipelinesde esta librería generan en la base de datos tres tablas adicionales para manejar los usuarios autenticados a través de redes sociales.

La tabla principal es la deusersocialauth, la cual nos permitirá vincularla con la claseUsery asignarle los siguientes campos:

• Provider: Nombre de la red social con la que el usuario se ha autenticado

• Uid: Identificador único del usuario

• Extra data:JSONcon eltimestampy el Token del usuario

Cuando se autentica un usuario a través deInstagram, el módulo crea por defecto un usuario basado en la claseUserpropia deDjangoy un usuario en la claseusersocialauth.

Así mismo, nuestra web también tiene que registrar si el usuario es un profesional o un usuario común. Para ello tenemos una función en el archivopipeline.pyque nos identifica si el usuario es nuevo y en caso de ser así pasa a mirar si se ha autenticado como profesional o no y a continuación crea el correspondiente objetoProfessionalo MyUseren la base de datos y lo asocia al usuario creado por el propio módulo.

Para poder distinguir los usuarios en elpipelinele pasamos por parámetro en la URLel tipo de usuario, el cual puede ser (ProfessionaloMyUser). De esta manera la llamada queda de la siguiente forma:

{ %u r l " s o c i a l : begin " " instagram " %}?next=/ signup_instagram_pro/&typeUser= P r o f e s s i o n a l "

El parámetronextnos permite indicar laURLa la cual queremos que nos redirija después de autenticar el usuario en la red social.

(44)
(45)

C

APÍTULO

6

F RONTEND

En elfrontendde nuestra web utilizamos elFramework Djangojunto al lenguaje de plantillasDjango templatesen su version 1.9.

Este lenguaje de etiquetas nos permite tratar objetos dePythondirectamente en HTMLsin interactuar con la base de datos, obteniendo un nivel de abstracción que permite mantener el modeloMVC.

Además nos permitirá hacer operaciones básicas comoforoif sobre los objetos de Pythony sus atributos.

6.1 Bower

A través deBowergestionaremos todas las dependenciasfrontenddel proyecto. En el archivobower.json, situado en la raíz del proyecto, en el apartado"dependencies", indi- caremos todas las librerías que necesitamos descargar directamente de los repositorios deGithuby el número de versión que nos interesa.

Aquí tenemos un ejemplo de como indicaremos al gestor de dependencias que cargue la libreríabootstrap:

" dependencies " : { . . .

" bootstrap " : " ^ 3 . 3 . 6 " , . . .

}

Estas dependencias se instarán al lanzar el contenedor de bower condockerel cual una vez que haya instalado todas las librerías desaparecerá y se guardaran en la carpeta bower_components, a la cual tendrá acceso el contenedor que contiene la aplicación web.

Referanser

RELATERTE DOKUMENTER

De esta manera todos los datos serán almacenados en una base de datos MySQL con la finalidad de mostrar todos los datos correspondientes a cada usuario de la aplicación web, se

Por esto, porque de lo que se trata es de proteger el domicilio como establece la CE y consecuentemente el ámbito más íntimo de desarrollo de la persona y

Posteriormente a la formación del [G(-H)·] un radical superóxido puede atacar a dicha especie, formando el I2, esta segunda especie tras una reducción dará lugar a la

El objetivo de este proyecto consistía en desarrollar una aplicación web para facilitar la gestión de las vacaciones y los recursos de las empresas tanto por

Una vez dados a conocer el concepto de turismo, su evolución y el concepto de imagen turística y su importancia, podremos dar lugar al objetivo principal y más importante de este

Para el presente estudio se ha desarrollado una metodología que demuestra claramente mediante indicadores los impactos del turismo y sus beneficios para la conservación de los

Este trabajo de Fin de Grado expone una revisión bibliográfica sobre las medidas establecidas con la Ley Orgánica 3/2007, para la Igualdad Efectiva entre Mujeres y

El objetivo es realizar una actualización del hardware de la primera invención descrita (mando de fuerza), incorporando sensores que permitan obtener más información de la persona