-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #88 from ES2-UFPI/dev
close issue#56: Fazendo o merge da aplicação para o deploy
- Loading branch information
Showing
19 changed files
with
544 additions
and
367 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,5 @@ | ||
# Ignore .env files | ||
.env | ||
src/utils/globals.py | ||
src/utils/globals.py | ||
__pycache__/ | ||
.pytest_cache |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,156 +1,161 @@ | ||
import streamlit as st | ||
import pandas as pd | ||
import plotly.graph_objects as go | ||
from utils import session, users, profiles | ||
from werkzeug.security import generate_password_hash, check_password_hash | ||
|
||
def plot_avg_game_ratings_plotly(reviews, jogos): | ||
if not reviews.empty: | ||
# Ajusta as notas para a escala de 0 a 5 | ||
reviews['nota'] = reviews['nota'] / 2 | ||
|
||
# Calcula a média de notas por jogo | ||
avg_ratings = reviews.groupby('jogo_id')['nota'].mean() | ||
avg_ratings = avg_ratings.to_frame().join(jogos.set_index('id')['title']).rename(columns={'nota': 'avg_rating', 'title': 'game_title'}) | ||
avg_ratings = avg_ratings.sort_values('avg_rating', ascending=False) | ||
|
||
# Criação do gráfico | ||
fig = go.Figure() | ||
|
||
for index, row in avg_ratings.iterrows(): | ||
fig.add_trace(go.Bar( | ||
x=[row['game_title']], | ||
x=[row['game_title']], | ||
y=[row['avg_rating']], | ||
text=[f"{'★' * int(round(row['avg_rating']))} ({row['avg_rating']:.1f})"], # Mostra estrelas e a nota | ||
text=[f"{'★' * int(round(row['avg_rating']))} ({row['avg_rating']:.1f})"], | ||
textposition='auto', | ||
)) | ||
|
||
# Personalizações adicionais | ||
fig.update_layout( | ||
title='Média de Notas por Jogo (em estrelas)', | ||
xaxis_title='Jogos', | ||
yaxis_title='Nota Média', | ||
yaxis=dict(range=[0,5]), # Define o limite do eixo y para 5 | ||
plot_bgcolor='rgba(0,0,0,0)' | ||
yaxis=dict(range=[0, 5]), | ||
plot_bgcolor='rgba(0, 0, 0, 0)' | ||
) | ||
|
||
return fig | ||
else: | ||
return None | ||
|
||
def load_data(): | ||
jogos = pd.read_csv("src/data/processed_data.csv") # Ajuste o caminho do arquivo se necessário | ||
jogos = pd.read_csv("src/data/processed_data.csv") | ||
jogos['id'] = range(1, len(jogos) + 1) | ||
return jogos | ||
|
||
# Função para carregar avaliações (simulação de dados persistidos) | ||
def load_reviews(): | ||
try: | ||
return pd.read_csv('src/data/reviews.csv') | ||
except FileNotFoundError: | ||
return pd.DataFrame(columns=["jogo_id", "usuario", "nota", "comentario", "favorito", "sentimento"]) | ||
|
||
def delete_account(user_id): | ||
# Deletar perfil | ||
session.query(profiles).filter(profiles.c.user_id == user_id).delete() | ||
# Deletar usuário | ||
session.query(users).filter(users.c.id == user_id).delete() | ||
session.commit() | ||
|
||
def profile_page(): | ||
if 'username' not in st.session_state or not st.session_state.get('logged_in', False): | ||
st.error('Por favor, faça login primeiro.') | ||
return | ||
|
||
username = st.session_state.username | ||
st.title('Perfil') | ||
st.sidebar.markdown("# Profile 👤") | ||
|
||
def get_user_profile(username): | ||
user = session.query(users).filter(users.c.username == username).first() | ||
profile = session.query(profiles).filter(profiles.c.user_id == user.id).first() | ||
|
||
if profile is None: | ||
profile = profiles.insert().values(user_id=user.id) | ||
session.execute(profile) | ||
session.commit() | ||
profile = session.query(profiles).filter(profiles.c.user_id == user.id).first() | ||
return user, profile | ||
|
||
st.sidebar.title("Minha Conta") | ||
settings_mode = st.sidebar.radio("Escolha uma opção:", ["Perfil", "Configurações da Conta"]) | ||
def display_profile(profile, user): | ||
edit_mode = st.session_state.get('edit_mode', False) | ||
|
||
if settings_mode == "Perfil": | ||
edit_mode = st.session_state.get('edit_mode', False) | ||
|
||
if edit_mode: | ||
with st.form("profile_info"): | ||
full_name = st.text_input("Nome Completo", value=profile.full_name if profile.full_name else "") | ||
bio = st.text_area("Bio", value=profile.bio if profile.bio else "") | ||
|
||
save_changes = st.form_submit_button("Salvar Alterações") | ||
if save_changes: | ||
session.query(profiles).filter(profiles.c.user_id == user.id).update({ | ||
'full_name': full_name, | ||
'bio': bio | ||
}) | ||
session.commit() | ||
st.session_state.edit_mode = False # Turn off edit mode after saving | ||
st.success("Perfil atualizado com sucesso!") | ||
|
||
st.form_submit_button("Cancelar", on_click=lambda: st.session_state.__setitem__('edit_mode', False)) | ||
else: | ||
st.write(f"**Nome Completo:** {profile.full_name if profile.full_name else 'Não definido'}") | ||
st.write(f"**Bio:** {profile.bio if profile.bio else 'Não definida'}") | ||
st.button("Editar", on_click=lambda: st.session_state.__setitem__('edit_mode', True)) | ||
if edit_mode: | ||
with st.form("profile_info"): | ||
full_name = st.text_input("Nome Completo", value=profile.full_name if profile.full_name else "") | ||
bio = st.text_area("Bio", value=profile.bio if profile.bio else "") | ||
|
||
st.write("---") | ||
st.write("**Avaliações**") | ||
save_changes = st.form_submit_button("Salvar Alterações") | ||
if save_changes: | ||
update_profile(user.id, full_name, bio) | ||
st.session_state.edit_mode = False | ||
st.success("Perfil atualizado com sucesso!") | ||
|
||
st.form_submit_button("Cancelar", on_click=lambda: st.session_state.__setitem__('edit_mode', False)) | ||
else: | ||
st.write(f"**Nome Completo:** {profile.full_name if profile.full_name else 'Não definido'}") | ||
st.write(f"**Bio:** {profile.bio if profile.bio else 'Não definida'}") | ||
st.button("Editar", on_click=lambda: st.session_state.__setitem__('edit_mode', True)) | ||
|
||
def update_profile(user_id, full_name, bio): | ||
session.query(profiles).filter(profiles.c.user_id == user_id).update({ | ||
'full_name': full_name, | ||
'bio': bio | ||
}) | ||
session.commit() | ||
|
||
reviews = load_reviews() | ||
user_reviews = reviews[reviews['usuario'] == username] | ||
def display_reviews(username): | ||
reviews = load_reviews() | ||
user_reviews = reviews[reviews['usuario'] == username] | ||
|
||
if not user_reviews.empty: | ||
jogos = load_data() | ||
user_reviews = user_reviews.merge(jogos[['id', 'title']], left_on='jogo_id', right_on='id') | ||
|
||
for _, row in user_reviews.iterrows(): | ||
st.write(f"**Jogo:** {row['title']}") | ||
st.write(f"**Nota:** {row['nota']}") | ||
st.write(f"**Comentário:** {row['comentario']}") | ||
st.write(f"**Favorito:** {'Sim' if row['favorito'] else 'Não'}") | ||
st.write("---") | ||
|
||
if st.button("Mostrar Gráfico de Avaliações"): | ||
fig = plot_avg_game_ratings_plotly(user_reviews, jogos) | ||
if fig: | ||
st.plotly_chart(fig) | ||
else: | ||
st.write("Você ainda não fez nenhuma avaliação.") | ||
|
||
if not user_reviews.empty: | ||
jogos = load_data() | ||
user_reviews = user_reviews.merge(jogos[['id', 'title']], left_on='jogo_id', right_on='id') | ||
def update_password(user_id, new_password): | ||
account_data = {'password': generate_password_hash(new_password)} | ||
session.query(users).filter(users.c.id == user_id).update(account_data) | ||
session.commit() | ||
|
||
for _, row in user_reviews.iterrows(): | ||
st.write(f"**Jogo:** {row['title']}") | ||
st.write(f"**Nota:** {row['nota']}") | ||
st.write(f"**Comentário:** {row['comentario']}") | ||
st.write(f"**Favorito:** {'Sim' if row['favorito'] else 'Não'}") | ||
st.write("---") | ||
def account_settings(user): | ||
with st.form("account_settings"): | ||
new_password = st.text_input("Nova Senha", type="password") | ||
confirm_password = st.text_input("Confirmar Nova Senha", type="password") | ||
|
||
save_changes = st.form_submit_button("Salvar Alterações") | ||
if save_changes: | ||
if new_password and new_password != confirm_password: | ||
st.error("As senhas não coincidem.") | ||
else: | ||
if new_password: | ||
update_password(user.id, new_password) | ||
st.success("Configurações de conta atualizadas com sucesso!") | ||
|
||
st.write("---") | ||
st.write("### Deletar Conta") | ||
if st.button("Deletar Conta"): | ||
confirm_delete = st.checkbox("Confirmar Deleção de Conta") | ||
if confirm_delete: | ||
delete_account(user.id) | ||
st.session_state.clear() | ||
st.success("Conta deletada com sucesso. Por favor, feche o aplicativo.") | ||
|
||
if st.button("Mostrar Gráfico de Avaliações"): | ||
fig = plot_avg_game_ratings_plotly(user_reviews, jogos) | ||
if fig: | ||
st.plotly_chart(fig) | ||
else: | ||
st.write("Você ainda não fez nenhuma avaliação.") | ||
def profile_page(): | ||
if 'username' not in st.session_state or not st.session_state.get('logged_in', False): | ||
st.error('Por favor, faça login primeiro.') | ||
return | ||
|
||
else: | ||
st.header("Configurações de Conta") | ||
username = st.session_state.username | ||
st.title('Perfil') | ||
st.sidebar.markdown("# Profile 👤") | ||
|
||
with st.form("account_settings"): | ||
new_password = st.text_input("Nova Senha", type="password") | ||
confirm_password = st.text_input("Confirmar Nova Senha", type="password") | ||
user, profile = get_user_profile(username) | ||
|
||
save_changes = st.form_submit_button("Salvar Alterações") | ||
if save_changes: | ||
if new_password and new_password != confirm_password: | ||
st.error("As senhas não coincidem.") | ||
else: | ||
if new_password: | ||
account_data = {'password': generate_password_hash(new_password)} | ||
session.query(users).filter(users.c.id == user.id).update(account_data) | ||
session.commit() | ||
st.success("Configurações de conta atualizadas com sucesso!") | ||
st.sidebar.title("Minha Conta") | ||
settings_mode = st.sidebar.radio("Escolha uma opção:", ["Perfil", "Configurações da Conta"]) | ||
|
||
if settings_mode == "Perfil": | ||
display_profile(profile, user) | ||
st.write("---") | ||
st.write("### Deletar Conta") | ||
if st.button("Deletar Conta"): | ||
confirm_delete = st.checkbox("Confirmar Deleção de Conta") | ||
if confirm_delete: | ||
delete_account(user.id) | ||
st.session_state.clear() | ||
st.success("Conta deletada com sucesso. Por favor, feche o aplicativo.") | ||
st.write("**Avaliações**") | ||
display_reviews(username) | ||
else: | ||
account_settings(user) | ||
|
||
if __name__ == "__main__": | ||
profile_page() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
from streamlit.testing.v1 import AppTest | ||
def test_busca(): | ||
at = AppTest.from_file("../🔎 Busca.py").run(timeout=50) | ||
assert not at.error, "Erro encontrado durante a execução inicial" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
from streamlit.testing.v1 import AppTest | ||
|
||
def test_login(): | ||
at = AppTest.from_file("../../login.py").run(timeout=50) | ||
assert not at.error, "Erro encontrado durante a execução inicial" | ||
|
||
at.text_input[0].input("luishmq").run(timeout=50) | ||
at.text_input[1].input("1234").run(timeout=50) | ||
at.button[0].click().run(timeout=20) | ||
|
||
assert at.error[0].value == "Nome de usuário ou senha incorretos" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
from streamlit.testing.v1 import AppTest | ||
|
||
def test_mario(): | ||
at = AppTest.from_file("../🤖 Mario.py").run(timeout=50) | ||
assert not at.error, "Erro encontrado durante a execução inicial" | ||
|
||
at.text_input[0].input("Qual jogo de corrida você recomenda?").run(timeout=50) | ||
at.button[0].click().run(timeout=20) | ||
assert at.markdown[2].value == "#### Resposta:" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
from streamlit.testing.v1 import AppTest | ||
import logging | ||
|
||
# Configuração de logging | ||
logging.basicConfig(level=logging.INFO) | ||
logger = logging.getLogger(__name__) | ||
|
||
def test_reviews(): | ||
try: | ||
at = AppTest.from_file("../🧠 Reviews.py").run(timeout=50) | ||
assert not at.error, f"Erro encontrado durante a execução inicial: {at.error}" | ||
logger.info("Teste inicial passado sem erros.") | ||
|
||
# Adicione qualquer verificação adicional que possa ser necessária aqui | ||
|
||
except Exception as e: | ||
logger.error(f"Exceção durante o teste: {e}") | ||
assert False, f"Exceção durante o teste: {e}" | ||
|
||
if __name__ == "__main__": | ||
test_reviews() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
from streamlit.testing.v1 import AppTest | ||
import logging | ||
|
||
# Configuração de logging | ||
logging.basicConfig(level=logging.INFO) | ||
logger = logging.getLogger(__name__) | ||
|
||
def test_wishlist(): | ||
try: | ||
at = AppTest.from_file("../✨ Wishlist.py").run(timeout=50) | ||
assert not at.error, f"Erro encontrado durante a execução inicial: {at.error}" | ||
logger.info("Teste inicial passado sem erros.") | ||
|
||
# Adicione qualquer verificação adicional que possa ser necessária aqui | ||
|
||
except Exception as e: | ||
logger.error(f"Exceção durante o teste: {e}") | ||
assert False, f"Exceção durante o teste: {e}" | ||
|
||
if __name__ == "__main__": | ||
test_reviews() |
Oops, something went wrong.