Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
38 commits
Select commit Hold shift + click to select a range
e50993c
Aqui edite el link de caracteristicas en base para poder ir a;adiendo…
marcs02 Jun 9, 2023
c8347ff
Aqui agregue lo del perfil, lo del logo y lo del fevicon, me falta po…
marcs02 Jun 10, 2023
8c9cabc
Esto preparando el cambio de imagen para el perfil
marcs02 Jun 11, 2023
efac54f
el mismo commit de antes
marcs02 Jun 11, 2023
694bd6e
aqui hice que se pueda ver el nombre de la persona registrada
marcs02 Jun 11, 2023
55a18bf
Aqui hago que el ususario pueda cambiar su nombre con las respectivas…
marcs02 Jun 11, 2023
d00282f
he podido mistrar los pokemones, me falta cambiar foto de perfil
marcs02 Jun 11, 2023
719116c
Aqui ya hice el cambio de imagen de perfil
marcs02 Jun 11, 2023
1df3528
Solucione un bug que habia con la imagen, aun no se me muestra en to…
marcs02 Jun 11, 2023
f275113
proyecto full kay
marcs02 Jun 11, 2023
1ffde72
El perfil aparece en todos los moduros, ya se puede solo cambiar la i…
marcs02 Jun 14, 2023
616f31e
Aqui estan los cambios de Tejada.
marcs02 Jul 4, 2023
4a06a64
El git ignore
marcs02 Aug 3, 2023
3897d04
Se agrego una nueva tabla llamada friends, y una nueva seccion llamad…
marcs02 Aug 3, 2023
737d656
Aqui se modificaron las forma de obtener en g.user, para poder mostra…
marcs02 Aug 5, 2023
ff188cc
Aqui ya pude agregar las imagenes a cada pokemon.
marcs02 Aug 5, 2023
63c6f12
Aqui le puse un marco a cada imagen de cada pokemon.
marcs02 Aug 9, 2023
ec3bc96
Aqui hice que se vean las imagenes de cada usuario, tambien arregle e…
marcs02 Aug 13, 2023
b090363
Aqui se creo una seccion nueva que se llama Post, donde el usuario va…
marcs02 Aug 17, 2023
b592e80
Aqui se ya la Seccion Posts Generales esta hecho, los usuarios pueden…
marcs02 Aug 17, 2023
a5998ad
Aqui se agrego el dise;o donde van a llegar las notificaciones
marcs02 Aug 17, 2023
607a89c
Aqui se agregaron las solicitudes de amistad, se pueden enviar y qui…
marcs02 Aug 19, 2023
26526ab
Aqui se agrego en CSS y HTML la parte del chat.
marcs02 Aug 19, 2023
77c8e6c
Aqui se le agregaron fuentes al menu donde van a ir los chats, y la p…
marcs02 Aug 19, 2023
669f1f0
nombre de la base de datos : poke
Socrates-Programmer Dec 15, 2023
b99dcd2
Codificaciones visuales en Signup and Login
Socrates-Programmer Jul 17, 2025
445d8dd
Modificaciones visuales a pokedex, post, driends, perfil
Socrates-Programmer Jul 17, 2025
b2043dc
Agregando docker-compose para subir web online
Socrates-Programmer Jul 17, 2025
aa4d5aa
Modificaciones de diseño a: Base, Base_perfil e index.
Socrates-Programmer Jul 17, 2025
79ce956
Se modifico docker-compose y dockerfile para poder correr la base de …
Socrates-Programmer Jul 17, 2025
b82da3b
Se agrego gunicorn a requirements.txt
Socrates-Programmer Jul 17, 2025
0ae83a2
Se agrego la base de datos online con Railway
Socrates-Programmer Jul 18, 2025
1b52abc
Dotenv agrego en requirements
Socrates-Programmer Jul 18, 2025
06815e1
Cambiando la ´f´ de Footer por mayuscula.
Socrates-Programmer Jul 18, 2025
cf6d1e1
Modificiacion del diseño del Nav-Bar
Socrates-Programmer Jul 18, 2025
cd86220
Modificando el footer
Socrates-Programmer Jul 18, 2025
f53db90
Add files via upload
Socrates-Programmer Oct 27, 2025
42b91e5
Poke user updated
Socrates-Programmer Oct 27, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
28 changes: 28 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
# Dockerfile para contenerizar la aplicación Flask de Pokédex
# Usa Python 3.10 slim como base
FROM python:3.10-slim

# Variables de entorno
ENV PYTHONDONTWRITEBYTECODE 1
ENV PYTHONUNBUFFERED 1

# Instala dependencias del sistema
RUN apt-get update && apt-get install -y \
build-essential \
default-libmysqlclient-dev \
&& rm -rf /var/lib/apt/lists/*

# Crea el directorio de la app
WORKDIR /app

# Copia los archivos de la aplicación
COPY . /app

# Instala las dependencias de Python
RUN pip install --upgrade pip && pip install -r requirements.txt

# Expone el puerto de Flask
EXPOSE 5000

# Comando para iniciar la app
CMD ["python", "poke/run.py"]
36 changes: 36 additions & 0 deletions docker-compose.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
version: '3.8'

services:
db:
image: mysql:8.0
restart: always
environment:
MYSQL_ROOT_PASSWORD: rootpass
MYSQL_DATABASE: poke
MYSQL_USER: poke_user
MYSQL_PASSWORD: poke_pass
volumes:
- poke_db_data:/var/lib/mysql
ports:
- "3307:3306"
healthcheck:
test: ["CMD-SHELL", "mysqladmin ping -h localhost -u root --password=rootpass"]
interval: 10s
timeout: 5s
retries: 5

web:
build: .
working_dir: /app
volumes:
- .:/app
ports:
- "5000:5000"
env_file: poke/.env
depends_on:
db:
condition: service_healthy
command: python poke/run.py

volumes:
poke_db_data:
26 changes: 26 additions & 0 deletions docker-entrypoint-initdb.d/init.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@

CREATE TABLE IF NOT EXISTS users (
id_user INT AUTO_INCREMENT PRIMARY KEY,
name VARCHAR(85) NOT NULL,
last_name VARCHAR(36) NOT NULL,
email VARCHAR(90) UNIQUE NOT NULL,
password VARCHAR(350) NOT NULL,
imagen LONGBLOB
);

CREATE TABLE IF NOT EXISTS user_post (
id INT AUTO_INCREMENT PRIMARY KEY,
message TEXT NOT NULL,
fecha TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
users_id_post INT,
FOREIGN KEY (users_id_post) REFERENCES users(id_user)
);

CREATE TABLE IF NOT EXISTS notification (
id INT AUTO_INCREMENT PRIMARY KEY,
receptor_id INT,
sender_id INT,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
FOREIGN KEY (receptor_id) REFERENCES users(id_user),
FOREIGN KEY (sender_id) REFERENCES users(id_user)
);
28 changes: 28 additions & 0 deletions init.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@

CREATE TABLE IF NOT EXISTS users (
id_user INT AUTO_INCREMENT PRIMARY KEY,
name VARCHAR(85) NOT NULL,
last_name VARCHAR(36) NOT NULL,
email VARCHAR(90) UNIQUE NOT NULL,
password VARCHAR(350) NOT NULL,
imagen LONGBLOB
);


CREATE TABLE IF NOT EXISTS user_post (
id INT AUTO_INCREMENT PRIMARY KEY,
message TEXT NOT NULL,
fecha TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
users_id_post INT,
FOREIGN KEY (users_id_post) REFERENCES users(id_user)
);


CREATE TABLE IF NOT EXISTS notification (
id INT AUTO_INCREMENT PRIMARY KEY,
receptor_id INT,
sender_id INT,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
FOREIGN KEY (receptor_id) REFERENCES users(id_user),
FOREIGN KEY (sender_id) REFERENCES users(id_user)
);
7 changes: 7 additions & 0 deletions init_db.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
# Entrypoint para inicializar la base de datos si es necesario
# Este script se puede usar en el contenedor de la base de datos

#!/bin/bash
set -e

mysql -u "$MYSQL_USER" -p"$MYSQL_PASSWORD" "$MYSQL_DATABASE" < /app/init.sql
7 changes: 7 additions & 0 deletions poke/.env
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
FLASK_DATABASE_HOST=yamabiko.proxy.rlwy.net
FLASK_DATABASE_USER=root
FLASK_DATABASE_PASSWORD=EgUprnPxtcwpiQjCGYrJuKVkGoPDTapw
FLASK_DATABASE=railway
FLASK_DATABASE_PORT=48098
SECRET_KEY=mikey
FLASK_DEBUG=1
7 changes: 4 additions & 3 deletions poke/.gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
.env
app/__pycache__
venv
.env/
uploads/
/app/__pycache__
../a
21 changes: 15 additions & 6 deletions poke/app/__init__.py
Original file line number Diff line number Diff line change
@@ -1,28 +1,37 @@
from flask import Flask
from flask import Flask, current_app
import os
from dotenv import load_dotenv
load_dotenv()


def create_app():
app = Flask(__name__)

app.config['UPLOAD_FOLDER'] = 'static'
app.config.from_mapping(
FROM_EMAIL=os.environ.get('FROM_EMAIL'),
SECRET_KEY=os.environ.get('SECRET_KEY'),
DATABASE_HOST=os.environ.get('FLASK_DATABASE_HOST'),
DATABASE_USER=os.environ.get('FLASK_DATABASE_USER'),
DATABASE_PASSWORD=os.environ.get('FLASK_DATABASE_PASSWORD'),
DATABASE=os.environ.get('FLASK_DATABASE')
DATABASE=os.environ.get('FLASK_DATABASE'),
DATABASE_PORT=os.environ.get('FLASK_DATABASE_PORT')
)

from . import db


from . import db
db.init_app(app)

from . import poke

app.register_blueprint(poke.bp)



from . import pokedex
app.register_blueprint(pokedex.bp, name='pokedex_blueprint')
app.register_blueprint(pokedex.bppoke, name='pokedex_blueprint')

from . import perfil
app.register_blueprint(perfil.bpp)


return app
Binary file added poke/app/__pycache__/__init__.cpython-310.pyc
Binary file not shown.
Binary file added poke/app/__pycache__/__init__.cpython-39.pyc
Binary file not shown.
Binary file added poke/app/__pycache__/db.cpython-310.pyc
Binary file not shown.
Binary file added poke/app/__pycache__/db.cpython-39.pyc
Binary file not shown.
Binary file added poke/app/__pycache__/perfil.cpython-39.pyc
Binary file not shown.
Binary file added poke/app/__pycache__/poke.cpython-310.pyc
Binary file not shown.
Binary file added poke/app/__pycache__/poke.cpython-39.pyc
Binary file not shown.
Binary file added poke/app/__pycache__/pokedex.cpython-310.pyc
Binary file not shown.
Binary file added poke/app/__pycache__/pokedex.cpython-39.pyc
Binary file not shown.
15 changes: 8 additions & 7 deletions poke/app/db.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,20 +6,21 @@
def get_db():
if 'db' not in g:
g.db = mysql.connector.connect(
host = current_app.config['DATABASE_HOST'],
user = current_app.config['DATABASE_USER'],
password = current_app.config['DATABASE_PASSWORD'],
database = current_app.config['DATABASE']
host=current_app.config['DATABASE_HOST'], # ✅ sin FLASK_
user=current_app.config['DATABASE_USER'],
password=current_app.config['DATABASE_PASSWORD'],
database=current_app.config['DATABASE'],
port=int(current_app.config['DATABASE_PORT'])
)

g.c = g.db.cursor(dictionary=True)

return g.db, g.c

def close_db(e=None):
db = g.pop('db', None)

if db is not None:
db.close()

def init_app(app):
app.teardown_appcontext(close_db)
app.teardown_appcontext(close_db)
159 changes: 159 additions & 0 deletions poke/app/perfil.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,159 @@
from flask import (
Blueprint, flash, g, redirect, render_template, request, url_for, current_app
)

import os
from flask import Flask, render_template, request, flash, redirect, url_for
from werkzeug.utils import secure_filename
import mysql.connector

from werkzeug.exceptions import abort
from app.poke import login_required
from app.db import get_db
from werkzeug.utils import secure_filename

import base64

import re
import functools

import base64
from flask import send_file

from flask import Flask, render_template, request
from werkzeug.utils import secure_filename
from os import path
import os


UPLOAD_FOLDER = os.path.join(os.getcwd(), 'uploads')
ALLOWED_EXTENSIONS = {'png', 'jpg', 'jpeg', 'gif'}

# Verificar si la carpeta de carga existe, si no, crearla
if not os.path.exists(UPLOAD_FOLDER):
os.makedirs(UPLOAD_FOLDER)

bpp = Blueprint('perfil', __name__, url_prefix='/perfil', static_folder='static')

def allowed_file(filename):
return '.' in filename and filename.rsplit('.', 1)[1].lower() in ALLOWED_EXTENSIONS

@bpp.route('/', methods=["GET", "POST"])
@login_required
def perfil():
db, c = get_db()
error = None
#Obtener el nombre del usuario de la base de datos
user_id = g.user['id_user']
# Obtener el ID del usuario actual desde la sesión

# Consulta para obtener las solicitudes de amistad recibidas por el usuario actual
c.execute("""
SELECT n.id, u.name AS sender_name, u.last_name AS sender_last_name, n.created_at
FROM notification n
JOIN users u ON n.sender_id = u.id_user
WHERE n.receptor_id = %s
ORDER BY n.created_at DESC
""", (user_id,))

received_requests = c.fetchall()


c.execute('SELECT name FROM users WHERE id_user = %s', (user_id,))
user = c.fetchone()
nombre_usuario = user['name'] if user else None

c.execute('SELECT last_name FROM users WHERE id_user = %s', (user_id,))
last = c.fetchone()
apellido_usuario = last['last_name'] if last else None

c.execute("SELECT imagen FROM users WHERE id_user = %s", (user_id,))
image_data = c.fetchone()
imagen_path = image_data['imagen'] if image_data else None

#Obtener el nombre del usuario de la base de datos////
# Antes del bloque if request.method == 'POST'
imagen_base64 = base64.b64encode(imagen_path).decode('utf-8') if imagen_path else None

# Obtener el Nombre, Apellido y foto de perfil del usuario de la base de datos
if request.method == 'POST':
new_name = request.form['new_name']
new_lastname = request.form['new_lastname']

if not error:
c.execute("UPDATE users SET name = %s, last_name = %s WHERE id_user = %s", (new_name, new_lastname, user_id))
db.commit()


flash('Se ha actualizado el nombre correctamente')

return redirect(url_for('perfil.perfil'))

# Convertir los datos de la imagen a una cadena base64
imagen_base64 = base64.b64encode(imagen_path).decode('utf-8') if imagen_path else None

return render_template('perfil/perfil.html', nombre_usuario=nombre_usuario, apellido_usuario=apellido_usuario, imagen_base64=imagen_base64, error=error, received_requests=received_requests)


# ...

@bpp.route('/upload', methods=['GET', 'POST'])
@login_required
def upload():
db, c = get_db()
error = None
#Obtener el nombre del usuario de la base de datos
user_id = g.user['id_user']
c.execute('SELECT name FROM users WHERE id_user = %s', (user_id,))
user = c.fetchone()
nombre_usuario = user['name'] if user else None

c.execute('SELECT last_name FROM users WHERE id_user = %s', (user_id,))
last = c.fetchone()
apellido_usuario = last['last_name'] if last else None

c.execute("SELECT imagen FROM users WHERE id_user = %s", (user_id,))
image_data = c.fetchone()
imagen_path = image_data['imagen'] if image_data else None

#Obtener el nombre del usuario de la base de datos////
# Antes del bloque if request.method == 'POST'
imagen_base64 = base64.b64encode(imagen_path).decode('utf-8') if imagen_path else None
if request.method == 'POST':
file = request.files['file']
user_id = g.user['id_user']

if not file:
error = 'File es requerido'
return render_template('perfil/perfil.html', nombre_usuario=nombre_usuario, apellido_usuario=apellido_usuario, imagen_base64=imagen_base64, error=error)

elif file and allowed_file(file.filename):
image_data = file.read()
# Resto del código...

# Guardar la imagen en la base de datos
cursor = db.cursor()
cursor.execute("UPDATE users SET imagen = %s WHERE id_user = %s", (image_data, user_id))
db.commit()

flash('Se ha actualizado el nombre correctamente')

return redirect(url_for('perfil.perfil'))

# Convertir los datos de la imagen a una cadena base64

return render_template('perfil/perfil.html')

@bpp.route('/imagen')
@login_required
def mostrar_imagen():
user_id = g.user['id_user']
db, c = get_db()
c.execute("SELECT imagen FROM users WHERE id_user = %s", (user_id,))
image_data = c.fetchone()
imagen_path = image_data['imagen'] if image_data else None

if imagen_path:
return send_file(imagen_path)

return abort(404)
Loading