diff --git a/Base de datos/uruguia_bd_test.sql b/Base de datos/uruguia_bd_test.sql index 485bd5d..f926f00 100644 --- a/Base de datos/uruguia_bd_test.sql +++ b/Base de datos/uruguia_bd_test.sql @@ -3,7 +3,7 @@ -- http://www.phpmyadmin.net -- -- Servidor: localhost --- Tiempo de generación: 21-02-2019 a las 23:16:09 +-- Tiempo de generación: 02-03-2019 a las 18:45:09 -- Versión del servidor: 5.5.24-log -- Versión de PHP: 5.4.3 @@ -57,6 +57,14 @@ CREATE TABLE IF NOT EXISTS `empresa` ( PRIMARY KEY (`id`) ) ENGINE=MyISAM DEFAULT CHARSET=utf8; +-- +-- Volcado de datos para la tabla `empresa` +-- + +INSERT INTO `empresa` (`id`, `nombre`) VALUES +(3, 'Empresa Falsa 1'), +(4, 'Empresa Falsa 2'); + -- -------------------------------------------------------- -- @@ -110,6 +118,14 @@ CREATE TABLE IF NOT EXISTS `turista` ( `pais_origen` varchar(100) NOT NULL ) ENGINE=MyISAM DEFAULT CHARSET=utf8; +-- +-- Volcado de datos para la tabla `turista` +-- + +INSERT INTO `turista` (`id`, `edad`, `pais_origen`) VALUES +(1, 25, 'Tangamandapio'), +(2, 31, 'Nosedonde'); + -- -------------------------------------------------------- -- @@ -125,7 +141,17 @@ CREATE TABLE IF NOT EXISTS `usuario` ( `tipo` varchar(100) NOT NULL, PRIMARY KEY (`id_usuario`), UNIQUE KEY `email` (`email`) -) ENGINE=MyISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 ; +) ENGINE=MyISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=5 ; + +-- +-- Volcado de datos para la tabla `usuario` +-- + +INSERT INTO `usuario` (`id_usuario`, `email`, `nombre`, `contrasena`, `foto`, `tipo`) VALUES +(1, 'test1@test1.com', 'Fulano de Tal', 'contrasenia', NULL, 'Turista'), +(2, 'test2@test2.com', 'Sultano de Tal', 'pass', NULL, 'Turista'), +(3, 'test3@test3.com', 'Senior de Negocios', 'passempresa', NULL, 'Empresa'), +(4, 'test4@test4.com', 'Seniora de Empresa', 'passempresa2', NULL, 'Empresa'); -- -------------------------------------------------------- diff --git a/Prototipo - Interfaz de Usuario/1-A Registro de usuario CARGADO.png b/Prototipo - Interfaz de Usuario/1-A Registro de usuario.png similarity index 100% rename from Prototipo - Interfaz de Usuario/1-A Registro de usuario CARGADO.png rename to Prototipo - Interfaz de Usuario/1-A Registro de usuario.png diff --git a/Prototipo - Interfaz de Usuario/1-B Login CARGADO.png b/Prototipo - Interfaz de Usuario/1-B Login.png similarity index 100% rename from Prototipo - Interfaz de Usuario/1-B Login CARGADO.png rename to Prototipo - Interfaz de Usuario/1-B Login.png diff --git a/Prototipo - Interfaz de Usuario/1-inicio CARGADO.png b/Prototipo - Interfaz de Usuario/1-inicio.png similarity index 100% rename from Prototipo - Interfaz de Usuario/1-inicio CARGADO.png rename to Prototipo - Interfaz de Usuario/1-inicio.png diff --git a/Prototipo - Interfaz de Usuario/2-A Vista Empresa.png b/Prototipo - Interfaz de Usuario/2-A Vista Empresa.png index 2897bb4..fa2220f 100644 Binary files a/Prototipo - Interfaz de Usuario/2-A Vista Empresa.png and b/Prototipo - Interfaz de Usuario/2-A Vista Empresa.png differ diff --git a/Prototipo - Interfaz de Usuario/2-A Vista Turista - dentro de categoria.png b/Prototipo - Interfaz de Usuario/2-A Vista Turista - dentro de categoria.png index 75350ad..209b5d0 100644 Binary files a/Prototipo - Interfaz de Usuario/2-A Vista Turista - dentro de categoria.png and b/Prototipo - Interfaz de Usuario/2-A Vista Turista - dentro de categoria.png differ diff --git a/README.md b/README.md index 171b308..9330649 100644 --- a/README.md +++ b/README.md @@ -8,14 +8,26 @@ Este es un pequeño manual para saber como están organizadas las cosas en el pr - Base de datos: Contiene el diagrama de la base de datos y un archivo SQL para cargar en WAMPServer. - Prototipo - Interfaz de usuario: Imagenes prototipo para implementar en el programa. - app: Contiene el programa. + - static: Contiene archivos estáticos (CSS y Javascript). + - templates: Contiene las plantillas HTML del programa. + -__init__.py: Inicia la aplicación en si. + - routes.py: Contiene las direcciones (routing) del sistema. - README.md: Esta guía. - Start-Server-bat: Si lo ejecutas en tu computadora cargará la aplicación en tu navegador. - uruguia.py: Este archivo carga todo lo de la carpeta "app". +## Setup +Para poder usar el sistema se debe tener instalado: +- Python 3 +- pip + - Flask + - flask-WTF + - pymysql +- Y tener abierta la base de datos del proyecto en WAMPServer. ### Base de datos La base de datos del proyecto está hecha en MySQL. Se debe descargar [WAMPServer](http://www.wampserver.es/#home), entrar en phpMyAdmin, crear una base de datos (por ejemplo, UruGuia_bd_test), entrar a ella y en la pestaña de SQL ingresar el contenido del archivo que se encuentra en la carpeta "Base de Datos". -### Enlance a la documentación +### Enlace a la documentación [Clic aquí](https://docs.google.com/document/d/1TsIIBK_cYJA3LC4x0MBcTItuWLZIk1NgaCrmfUnJ-nE/edit?usp=sharing). \ No newline at end of file diff --git a/app/__init__.py b/app/__init__.py index 5bdbcd0..6cd8550 100644 --- a/app/__init__.py +++ b/app/__init__.py @@ -1,6 +1,7 @@ from flask import Flask +from config import Config app = Flask(__name__) +app.config.from_object(Config) -from app import routes - +from app import routes \ No newline at end of file diff --git a/app/__pycache__/__init__.cpython-37.pyc b/app/__pycache__/__init__.cpython-37.pyc deleted file mode 100644 index 98f65da..0000000 Binary files a/app/__pycache__/__init__.cpython-37.pyc and /dev/null differ diff --git a/app/__pycache__/routes.cpython-37.pyc b/app/__pycache__/routes.cpython-37.pyc deleted file mode 100644 index 4f36a44..0000000 Binary files a/app/__pycache__/routes.cpython-37.pyc and /dev/null differ diff --git a/app/forms.py b/app/forms.py new file mode 100644 index 0000000..d393788 --- /dev/null +++ b/app/forms.py @@ -0,0 +1,25 @@ +from flask_wtf import FlaskForm +from wtforms import StringField, PasswordField, BooleanField, SubmitField +from wtforms.validators import DataRequired +from wtforms.fields.html5 import EmailField +# Este archivo contiene todos los formularios del sistema. + +class LoginForm(FlaskForm): + # validators argument es para validaciones. + # DataRequired chequea que no estén vacíos, aunque existen más validaciones. + email = EmailField('Email', validators=[DataRequired()]) + password = PasswordField('Contraseña', validators=[DataRequired()]) + submit = SubmitField("Iniciar sesión") + +class RegisterForm(FlaskForm): + email = EmailField('Email') + nombre = StringField('Nombre y apellido') + password = PasswordField('Contraseña') + # foto? + tipo = StringField('Tipo') + # TURISTA + edad = StringField('Edad') + pais = StringField('País de origen') + # EMPRESA + nombreEmpresa = StringField('Nombre de la empresa') + submit = SubmitField("Crear usuario") \ No newline at end of file diff --git a/app/routes.py b/app/routes.py index 2ecacf0..8b18ac9 100644 --- a/app/routes.py +++ b/app/routes.py @@ -1,16 +1,143 @@ -from flask import render_template +from flask import render_template, flash, redirect, session, request from app import app +from app.forms import LoginForm, RegisterForm +import pymysql.cursors -@app.route('/') -@app.route('/index') +# Connect to the database +connection = pymysql.connect(host='localhost', + user='root', + password='', + db='uruguia_bd_test', + charset='utf8mb4', + cursorclass=pymysql.cursors.DictCursor) + + +@app.route('/', methods=['GET', 'POST']) +@app.route('/index', methods=['GET', 'POST']) def bienvenido(): - return render_template('bienvenido.html') + if session.get('logueado'): + return redirect('/principal') + else: + form = LoginForm() # Formulario de forms.py, se importa + if form.validate_on_submit(): #Al submitear data se corre esto + with connection.cursor() as cursor: + email=form.email.data + password=form.password.data + query = "SELECT id_usuario, email, nombre, tipo FROM usuario WHERE email=%s AND contrasena=%s" + cursor.execute(query,(email,password)) + userdata = cursor.fetchone() + results = cursor.rowcount + if results==0: + flash('Usuario y/o contraseña inválidos') + session['invalid_user']="true" + return redirect('/') + else: + session.pop('invalid_user', None) + session['logueado']=True + session['id_usuario'] = userdata['id_usuario'] + session['email'] = userdata['email'] + session['nombre'] = userdata['nombre'] + session['tipo'] = userdata['tipo'] + return redirect('/principal') + return render_template('bienvenido.html', form=form) -@app.route('/index/registro') +@app.route('/index/registro', methods=['GET', 'POST']) def registro(): - return render_template('registro.html') + if session.get('logueado'): + return redirect('/principal') + else: + nuevo = request.args.to_dict() + form = RegisterForm() + if form.validate_on_submit(): + try: + with connection.cursor() as cursor: + email = form.email.data + nombre = form.nombre.data + password = form.password.data + tipo = nuevo['tipo'] + query = """ + INSERT INTO usuario + (email,nombre,contrasena,tipo) + VALUES + (%s,%s,%s,%s) + """ + cursor.execute(query,(email,nombre,password,tipo)) + query = """ + SELECT id_usuario FROM usuario + WHERE email=%s + """ + cursor.execute(query,(email)) + userdata = cursor.fetchone() + id_usuario=userdata['id_usuario'] + + if nuevo['tipo']=='turista': + edad = form.edad.data + pais = form.pais.data + query = """ + INSERT INTO turista + (id,edad,pais_origen) + VALUES + (%s,%s,%s) + """ + cursor.execute(query,(id_usuario,edad,pais)) + else: + nombreEmpresa = form.nombreEmpresa.data + query = """ + INSERT INTO empresa + (id,nombre) + VALUES + (%s,%s) + """ + cursor.execute(query,(id_usuario,nombreEmpresa)) + connection.commit() + session.clear() + return redirect('/index') + except NameError: + print('Algo malo acaba de ocurrir: ' + NameError) + return render_template('registro.html', form=form,tipo=nuevo['tipo']) @app.route('/principal') def index(): + if session.get('logueado'): + print('ok') + else: + session.clear() + return redirect('/') return render_template('principal.html') +@app.route('/principal/usuario') +def usuario(): + if session.get('logueado'): + print('ok') + else: + session.clear() + return redirect('/') + return render_template('usuario.html') + + +@app.route('/logout') +def logout(): + try: + idu = request.args.to_dict() + iduINT = int(idu['id_usuario']) + ses = int(session['id_usuario']) + with connection.cursor() as cursor: + query = """ + DELETE FROM usuario WHERE id_usuario=%s + """ + cursor.execute(query,(ses)) + if session['tipo']=='turista': + query = """ + DELETE FROM turista WHERE id=%s + """ + cursor.execute(query,(ses)) + else: + query = """ + DELETE FROM empresa WHERE id=%s + """ + cursor.execute(query,(ses)) + connection.commit() + except: + print("Logout") + session.clear() + return redirect('/') diff --git a/app/static/css/style.css b/app/static/css/style.css index 02759b7..0965ade 100644 --- a/app/static/css/style.css +++ b/app/static/css/style.css @@ -4,6 +4,7 @@ performance de la aplicación.*/ @import "welcome.css"; @import "registro.css"; @import "principal.css"; +@import "usuario.css"; html, body { height: 80%; @@ -11,7 +12,8 @@ html, body { } nav { - background-color: blue; + background-color: red; + text-align: center; } nav ul{ diff --git a/app/static/css/usuario.css b/app/static/css/usuario.css new file mode 100644 index 0000000..40241d4 --- /dev/null +++ b/app/static/css/usuario.css @@ -0,0 +1,9 @@ +#danger-zone{ + background-color: tomato; + color: white; + padding: 5px; +} + +#confirmar-borrar-usuario{ + display: none; +} diff --git a/app/static/css/welcome.css b/app/static/css/welcome.css index ce97a6c..c48e38f 100644 --- a/app/static/css/welcome.css +++ b/app/static/css/welcome.css @@ -31,6 +31,11 @@ al resto del CSS sin tener que dejarlo aparte (me explico?).*/ flex-direction: column; } +.error{ + color:red; + font-weight: bold; +} + /*Button fix?*/ button{ width: 100%; @@ -54,5 +59,4 @@ button{ #login-show{ display: block; } - /* FIN DE CSS EXCLUSIVO DE BIENVENIDA, REFACTORIZAR POR DIOS*/ \ No newline at end of file diff --git a/app/static/script.js b/app/static/script.js index c2e01ee..fbe0730 100644 --- a/app/static/script.js +++ b/app/static/script.js @@ -12,4 +12,13 @@ function botonAlLogin(){ }else{ document.getElementById("login-show").setAttribute("id","login-hidden"); } +} + +function confirmarBorrarUsuario(){ + var d = document.getElementById("confirmar-borrar-usuario"); + if(d.style.display=="none"){ + d.style.display="block"; + }else{ + d.style.display="none"; + } } \ No newline at end of file diff --git a/app/templates/base.html b/app/templates/base.html index d771317..32fd33d 100644 --- a/app/templates/base.html +++ b/app/templates/base.html @@ -1,16 +1,24 @@ - {% if title %} - {% else %} - {% endif %} - {{ title }} - + - diff --git a/app/templates/login.html b/app/templates/login.html new file mode 100644 index 0000000..ccc0b4e --- /dev/null +++ b/app/templates/login.html @@ -0,0 +1,24 @@ +{% extends "base.html" %} + +{% block content %} +

Sign In

+
+ {{ form.hidden_tag() }} +

+ {{ form.username.label }}
+ {{ form.username(size=32) }}
+ {% for error in form.username.errors %} + [{{ error }}] + {% endfor %} +

+

+ {{ form.password.label }}
+ {{ form.password(size=32) }}
+ {% for error in form.password.errors %} + [{{ error }}] + {% endfor %} +

+ +

{{ form.submit() }}

+
+{% endblock %} \ No newline at end of file diff --git a/app/templates/principal.html b/app/templates/principal.html index 503db70..9a6be21 100644 --- a/app/templates/principal.html +++ b/app/templates/principal.html @@ -12,14 +12,15 @@
  • Logo
  • Opción
  • Opción
  • -
  • Perfil usuario
  • -
  • Cerrar sesión
  • +
  • {{ session['nombre'] }}
  • +
  • Cerrar sesión
  • - + + {% if session['tipo']=='turista' %}
    - + Clima
    @@ -34,12 +35,14 @@
  • Categoria
  • + {% else %}
    Agregar
    - +
    + {% endif %} diff --git a/app/templates/registro.html b/app/templates/registro.html index 590664b..9578edc 100644 --- a/app/templates/registro.html +++ b/app/templates/registro.html @@ -10,28 +10,40 @@
    Imagen de mascota?
    -
    -
    - Imagen tuya -
    -
    - Nombre y apellido: - Email: - Contraseña: - Usted es: Turista
    - Empresa
    -
    -
    - - Nombre y apellido: - País de origen: - - Nombre de la empresa: - -
    - - - + + {{ form.hidden_tag() }} +

    + {{ form.email.label }}
    + {{ form.email(size=32) }}
    +

    +

    + {{ form.nombre.label }}
    + {{ form.nombre(size=32) }}
    +

    +

    + {{ form.password.label }}
    + {{ form.password(size=32) }}
    +

    +

    + Acá te dejaría subir foto pero no está definido
    + El tipo de usuario está en una variable de sesión +

    + {% if tipo=="turista" %} +

    + {{ form.edad.label }}
    + {{ form.edad(size=32) }}
    +

    +

    + {{ form.pais.label }}
    + {{ form.pais(size=32) }}
    +

    + {% else %} +

    + {{ form.nombreEmpresa.label }}
    + {{ form.nombreEmpresa(size=32) }}
    +

    + {% endif %} +

    {{ form.submit() }}

    diff --git a/app/templates/usuario.html b/app/templates/usuario.html new file mode 100644 index 0000000..98f7a87 --- /dev/null +++ b/app/templates/usuario.html @@ -0,0 +1,34 @@ + + + + ¡Bienvenido a UruGuía! + + + + + +
    +
    + +
    +
    +
    + ATENCIÓN: ESTÁS ENTRANDO A LA ZONA DE PELIGRO. LA INTEGRIDAD DE TU CUENTA ESTÁ COMPROMETIDA SI INTERACTÚAS CON EL CONTENIDO DE ESTA ZONA.
    + +
    + SI REALMENTE ESTÁS SEGURO DE QUERER BORRAR TU USUARIO, CONFIRMALO: + +
    +
    +
    +
    + + diff --git a/config.py b/config.py new file mode 100644 index 0000000..7acd108 --- /dev/null +++ b/config.py @@ -0,0 +1,11 @@ +import os + +class Config(object): + # La variable de configuración SECRET_KEY es muy importante, + # ya que muchas extensiones de Flask la utilizan como valor + # criptográfico. Flask-WTF la usa para evitar ataques Cross + # Site Request Forgery. Sería buena idea investigarla un poco. + SECRET_KEY = os.environ.get('SECRET_KEY') or 'you-will-never-guess' + # Una vez creada hay que decirle a Flask que la use. + # routes.py usa app.config.from_object para usarla. + # uruguia.py también. \ No newline at end of file diff --git a/uruguia.py b/uruguia.py index e524e69..6069001 100644 --- a/uruguia.py +++ b/uruguia.py @@ -1 +1,2 @@ -from app import app \ No newline at end of file +from app import app +app.config['SECRET_KEY'] \ No newline at end of file