diff --git a/dashboard/auth.py b/dashboard/auth.py index 82e7fe4..33dcc04 100644 --- a/dashboard/auth.py +++ b/dashboard/auth.py @@ -58,6 +58,7 @@ def try_login_using_cookies(): return login(*credentials) return None + def authenticate(): if st.secrets.get("skip_auth", False): login(os.environ["ADMIN"]) diff --git a/dashboard/import_csv.py b/dashboard/import_csv.py index 3ec829d..5d5dea6 100644 --- a/dashboard/import_csv.py +++ b/dashboard/import_csv.py @@ -1,61 +1,68 @@ -import pandas as pd -from models import JournalPaper, Journal, Person, ConferencePresentation, Book, BookChapter import Levenshtein +import pandas as pd +from models import ( + Book, + BookChapter, + ConferencePresentation, + Journal, + JournalPaper, + Person, +) df = pd.read_csv("/src/data/profesores.csv") people = Person.all() matches = { - 'Jose Luis Castañeda Lorenzo' : 'José Luis Castañeda Lorenzo' , - 'Ernesto Alejandro Lopez Cadalso' : 'Ernesto Alejandro López Cadalso' , - 'Juan Pablo Consuegra Ayala' : 'Juan Pablo Consuegra Ayala' , - 'Suilan Estevez Velarde' : 'Suilan Estévez Velarde' , - 'Maria Elvira Fernandez Sa' : 'María Elvira Fernández Sa' , - 'Alejandro Piad Morffis' : 'Alejandro Piad Morffis' , - 'Carmen Teresa Fernandez Montoto' : 'Carmen Fernández' , - 'Lucina Garcia Hernandez' : 'Lucina García' , - 'Yudivian Almeida Cruz' : 'Yudivián Almeida Cruz' , - 'Luciano Garcia Garrido' : 'Luciano García' , - 'Alberto Fernandez Oliva' : 'Alberto Fernández ' , - 'Joanna Campbell Amos' : 'Joanna Campbell Amos' , - 'Juan Enrique Morales Calvo' : 'Juan Enrique Morales Calvo' , - 'Aracelys Garcia Armenteros' : 'Aracelys García Armenteros' , - 'Eduardo Quesada Orozco' : 'Eduardo Quesada Orozco' , - 'Gemayqzel Bouza Allende' : 'Gemayqzel Bouza Allende' , - 'Jose Alejandro Mesejo Chiong' : 'Jose A. Mesejo Chiong' , - 'Damian Valdes Santiago' : 'Damian Valdés Santiago' , - 'Fernando R. Rodriguez Flores' : 'Fernando Rodriguez Flores' , - 'Elianys Garcia - Pola Cordoves' : 'Elianys García-Pola Cordobes' , - 'Aymee De Los Angeles Marrero Severo' : 'Aymée Marrero Severo' , - 'Julian Sarria Gonzalez' : 'Julián Sarría González' , - 'Sofia Behar Jequin' : 'Sofía Behar Jequín' , - 'Yanet Garcia Serrano' : 'Yanet Garcia Serrano' , - 'Vivian Del R. Sistachs Vega' : 'Vivian del Rosario Sistachs Vega' , - 'Carlos Narciso Bouza Herrera' : 'Carlos Bouza Herrera' , - 'Sira Maria Allende Alonso' : 'Sira Allende Alonso' , - 'Miraida Ferras Ferras' : 'Miraida Ferras Ferras' , - 'Marta Lourdes Baguer Diaz Romanach' : 'Marta L. Baguer Diaz-Romanach' , - 'Angela Mireya Leon Mecias' : 'Ángela Mireya León Mecías' , - 'Frank Michel Enrique Hevia' : 'Frank Michel Enrique Hevia' , - 'Wilfredo Morales Lezca' : 'Wilfredo Morales Lezca' , - 'Marcel Ernesto Sanchez Aguilar' : 'Marcel Ernesto Sánchez Aguilar' , - 'Jorge Estrada Hernandez' : 'Jorge Estrada Hernández' , - 'Ernesto Luis Estevanell Valladares' : 'Ernesto Luis Estevanell Valladares' , - 'Daniel Alejandro Valdes Perez' : 'Daniel Valdés Pérez' , - 'Alejandro Roque Piedra' : 'Alejandro Roque Piedra' , - 'Jose Fidel Hernandez Advincula' : 'José Fidel Hernández Advíncula' , - 'Celia Tamara Gonzalez Gonzalez' : 'Celia T. González González' , - 'Juan Carlos Lopez Realpozo' : 'Juan Pablo Consuegra Ayala' , - 'Marleny Soler Martinez' : 'Marleny Soler Martínez' , - 'Roxana Cabrera Puig' : 'Roxana Cabrera Puig' , - 'Reynaldo Rodriguez Ramos' : 'Reinaldo Rodríguez Ramos' , - 'Mariano Rodriguez Ricard' : 'Mariano Rodríguez Ricard' , - 'Jose Enrique Valdes Castro' : 'Jose Enrique Valdes Castro' , - 'Joaquin Alberto Herrera Macias' : 'Joaquín Alberto Herrera Macías' , - 'Lisset Suarez Plasencia' : 'Lisset Suárez Plasencia' , - 'Yeneit Delgado Kios' : 'Yeneit Delgado Kios' , - 'Ernesto Alejandro Borrego Rodriguez' : 'Ernesto Borrego Rodríguez' , + "Jose Luis Castañeda Lorenzo": "José Luis Castañeda Lorenzo", + "Ernesto Alejandro Lopez Cadalso": "Ernesto Alejandro López Cadalso", + "Juan Pablo Consuegra Ayala": "Juan Pablo Consuegra Ayala", + "Suilan Estevez Velarde": "Suilan Estévez Velarde", + "Maria Elvira Fernandez Sa": "María Elvira Fernández Sa", + "Alejandro Piad Morffis": "Alejandro Piad Morffis", + "Carmen Teresa Fernandez Montoto": "Carmen Fernández", + "Lucina Garcia Hernandez": "Lucina García", + "Yudivian Almeida Cruz": "Yudivián Almeida Cruz", + "Luciano Garcia Garrido": "Luciano García", + "Alberto Fernandez Oliva": "Alberto Fernández ", + "Joanna Campbell Amos": "Joanna Campbell Amos", + "Juan Enrique Morales Calvo": "Juan Enrique Morales Calvo", + "Aracelys Garcia Armenteros": "Aracelys García Armenteros", + "Eduardo Quesada Orozco": "Eduardo Quesada Orozco", + "Gemayqzel Bouza Allende": "Gemayqzel Bouza Allende", + "Jose Alejandro Mesejo Chiong": "Jose A. Mesejo Chiong", + "Damian Valdes Santiago": "Damian Valdés Santiago", + "Fernando R. Rodriguez Flores": "Fernando Rodriguez Flores", + "Elianys Garcia - Pola Cordoves": "Elianys García-Pola Cordobes", + "Aymee De Los Angeles Marrero Severo": "Aymée Marrero Severo", + "Julian Sarria Gonzalez": "Julián Sarría González", + "Sofia Behar Jequin": "Sofía Behar Jequín", + "Yanet Garcia Serrano": "Yanet Garcia Serrano", + "Vivian Del R. Sistachs Vega": "Vivian del Rosario Sistachs Vega", + "Carlos Narciso Bouza Herrera": "Carlos Bouza Herrera", + "Sira Maria Allende Alonso": "Sira Allende Alonso", + "Miraida Ferras Ferras": "Miraida Ferras Ferras", + "Marta Lourdes Baguer Diaz Romanach": "Marta L. Baguer Diaz-Romanach", + "Angela Mireya Leon Mecias": "Ángela Mireya León Mecías", + "Frank Michel Enrique Hevia": "Frank Michel Enrique Hevia", + "Wilfredo Morales Lezca": "Wilfredo Morales Lezca", + "Marcel Ernesto Sanchez Aguilar": "Marcel Ernesto Sánchez Aguilar", + "Jorge Estrada Hernandez": "Jorge Estrada Hernández", + "Ernesto Luis Estevanell Valladares": "Ernesto Luis Estevanell Valladares", + "Daniel Alejandro Valdes Perez": "Daniel Valdés Pérez", + "Alejandro Roque Piedra": "Alejandro Roque Piedra", + "Jose Fidel Hernandez Advincula": "José Fidel Hernández Advíncula", + "Celia Tamara Gonzalez Gonzalez": "Celia T. González González", + "Juan Carlos Lopez Realpozo": "Juan Pablo Consuegra Ayala", + "Marleny Soler Martinez": "Marleny Soler Martínez", + "Roxana Cabrera Puig": "Roxana Cabrera Puig", + "Reynaldo Rodriguez Ramos": "Reinaldo Rodríguez Ramos", + "Mariano Rodriguez Ricard": "Mariano Rodríguez Ricard", + "Jose Enrique Valdes Castro": "Jose Enrique Valdes Castro", + "Joaquin Alberto Herrera Macias": "Joaquín Alberto Herrera Macías", + "Lisset Suarez Plasencia": "Lisset Suárez Plasencia", + "Yeneit Delgado Kios": "Yeneit Delgado Kios", + "Ernesto Alejandro Borrego Rodriguez": "Ernesto Borrego Rodríguez", } for i, row in df.iterrows(): @@ -68,7 +75,7 @@ else: person = Person(name=name) - person.institution="Universidad de La Habana" + person.institution = "Universidad de La Habana" person.faculty = "Matemática y Computación" person.department = department person.scientific_grade = academic_grade diff --git a/dashboard/models/__init__.py b/dashboard/models/__init__.py index 0a19d47..4d0b1c5 100644 --- a/dashboard/models/__init__.py +++ b/dashboard/models/__init__.py @@ -1,10 +1,9 @@ +from models.custom_model import CustomModel from models.data_models.award_model import Award from models.data_models.book_chapter_model import BookChapter from models.data_models.book_model import Book from models.data_models.classes_model import Classes -from models.data_models.conference_presentation_model import ( - ConferencePresentation, -) +from models.data_models.conference_presentation_model import ConferencePresentation from models.data_models.journal_model import Journal from models.data_models.journal_paper_model import JournalPaper from models.data_models.person_model import Person @@ -13,4 +12,3 @@ from models.data_models.research_group_model import ResearchGroup from models.data_models.subject_model import Subject from models.data_models.thesis_model import Thesis -from models.custom_model import CustomModel diff --git a/dashboard/models/custom_model.py b/dashboard/models/custom_model.py index d05eb6b..c83065f 100644 --- a/dashboard/models/custom_model.py +++ b/dashboard/models/custom_model.py @@ -47,7 +47,6 @@ def with_refs(model_class: ModelT) -> ModelT: fields = model_class.__fields__ for field_name, field in fields.items(): if isclass(field.type_) and issubclass(field.type_, Ref): - # Function that returns a validator for a Ref[T] field def _ref_val_wrapper(field): def ref_val(cls, value): @@ -62,7 +61,6 @@ def ref_val(cls, value): ) elif isclass(field.type_) and issubclass(field.type_, RefList): - # Function that returns a validator for a RefList[T] field def _reflist_val_wrapper(field): def ref_list_val(cls, value): diff --git a/dashboard/models/data_models/book_model.py b/dashboard/models/data_models/book_model.py index 3a7b625..522639a 100644 --- a/dashboard/models/data_models/book_model.py +++ b/dashboard/models/data_models/book_model.py @@ -1,7 +1,6 @@ -from pydantic import HttpUrl - from models.custom_model import collection_name, with_refs from models.data_models.publication_model import Publication +from pydantic import HttpUrl @with_refs diff --git a/dashboard/models/data_models/conference_presentation_model.py b/dashboard/models/data_models/conference_presentation_model.py index db5eeef..01a4279 100644 --- a/dashboard/models/data_models/conference_presentation_model.py +++ b/dashboard/models/data_models/conference_presentation_model.py @@ -1,7 +1,6 @@ -from pydantic import HttpUrl - from models.custom_model import collection_name, with_refs from models.data_models.publication_model import Publication +from pydantic import HttpUrl @with_refs diff --git a/dashboard/models/data_models/journal_model.py b/dashboard/models/data_models/journal_model.py index 37675ca..8d9c9b9 100644 --- a/dashboard/models/data_models/journal_model.py +++ b/dashboard/models/data_models/journal_model.py @@ -1,8 +1,7 @@ from typing import List -from pydantic import Field, HttpUrl - from models.custom_model import CustomModel, collection_name +from pydantic import Field, HttpUrl @collection_name("journals") diff --git a/dashboard/models/data_models/journal_paper_model.py b/dashboard/models/data_models/journal_paper_model.py index 881ea6e..256ea6e 100644 --- a/dashboard/models/data_models/journal_paper_model.py +++ b/dashboard/models/data_models/journal_paper_model.py @@ -1,9 +1,8 @@ -from pydantic import HttpUrl - from models.custom_model import Ref, collection_name, with_refs from models.data_models.journal_model import Journal from models.data_models.person_model import Person from models.data_models.publication_model import Publication +from pydantic import HttpUrl @with_refs diff --git a/dashboard/models/data_models/project_model.py b/dashboard/models/data_models/project_model.py index 492777a..28f09a3 100644 --- a/dashboard/models/data_models/project_model.py +++ b/dashboard/models/data_models/project_model.py @@ -2,7 +2,6 @@ from typing import List import streamlit as st - from models.custom_model import CustomModel, Ref, RefList, collection_name, with_refs from models.data_models.person_model import Person diff --git a/dashboard/models/permission.py b/dashboard/models/permission.py index 1fa1f88..565a5c9 100644 --- a/dashboard/models/permission.py +++ b/dashboard/models/permission.py @@ -9,11 +9,7 @@ WRITE = 2 ADMIN = 4 -PERMISSIONS = { - READ: "Lectura", - WRITE: "Escritura", - ADMIN: "Administrador" -} +PERMISSIONS = {READ: "Lectura", WRITE: "Escritura", ADMIN: "Administrador"} PERMISSIONS_BY_NAME = {v: k for k, v in PERMISSIONS.items()} ALL_PERMISSIONS = reduce(lambda p1, p2: p1 | p2, PERMISSIONS.keys()) diff --git a/dashboard/modules/graph.py b/dashboard/modules/graph.py index bab21de..14b3dae 100644 --- a/dashboard/modules/graph.py +++ b/dashboard/modules/graph.py @@ -1,128 +1,159 @@ -from streamlit_agraph import agraph, Node, Edge, Config -from modules.utils import darken_color, select_color -from modules.utils import count_theses_by_advisor, count_theses_between_two_advisors -from modules.utils import count_publications_by_person, count_publications_between_two_persons - from typing import List, Tuple -from models import Person from uuid import UUID +from models import Person +from modules.utils import ( + count_publications_between_two_persons, + count_publications_by_person, + count_theses_between_two_advisors, + count_theses_by_advisor, + darken_color, + select_color, +) +from streamlit_agraph import Config, Edge, Node, agraph + + class NodeGraph: - def __init__(self, info: Person, size = 25, color = '#ACDBC9') -> None: + def __init__(self, info: Person, size=25, color="#ACDBC9") -> None: self.info = info self.color = color self.size = size + class EdgeGraph: - def __init__(self, source:NodeGraph, target:NodeGraph, info, color='#ACDBC9') -> None: + def __init__( + self, source: NodeGraph, target: NodeGraph, info, color="#ACDBC9" + ) -> None: self.source = source self.target = target self.info = info self.color = color - -def build_advisors_graph( advisors, theses ) -> any: + +def build_advisors_graph(advisors, theses) -> any: nodes = [] edges = [] - count_theses = count_theses_by_advisor( theses ) + count_theses = count_theses_by_advisor(theses) max_theses = max(count_theses.values()) for advisor in advisors: - nodes.append(Node( - id=advisor, - label=advisor, - title=f"{advisor}\n{count_theses[ advisor ]} tesis", - color=darken_color('#ACDBC9', count_theses[advisor], 2*max_theses), - size=25 + count_theses[advisor] * 3, - )) + nodes.append( + Node( + id=advisor, + label=advisor, + title=f"{advisor}\n{count_theses[ advisor ]} tesis", + color=darken_color("#ACDBC9", count_theses[advisor], 2 * max_theses), + size=25 + count_theses[advisor] * 3, + ) + ) for thesis in theses: for advisor in thesis.advisors: for advisor_2 in thesis.advisors: if advisor == advisor_2: - continue - count_thesis = count_theses_between_two_advisors( theses, advisor, advisor_2 ) - edges.append( Edge( - source=advisor, - label=f"{count_thesis} tesis", - target=advisor_2, - color=darken_color('#52FFCC', count_thesis, max_theses ), - directed=False, - collapsible=False - )) - - config = Config( width=900, height=700 ) + continue + count_thesis = count_theses_between_two_advisors( + theses, advisor, advisor_2 + ) + edges.append( + Edge( + source=advisor, + label=f"{count_thesis} tesis", + target=advisor_2, + color=darken_color("#52FFCC", count_thesis, max_theses), + directed=False, + collapsible=False, + ) + ) + + config = Config(width=900, height=700) return agraph(nodes=nodes, edges=edges, config=config) - -def build_nodes_and_edges( publications: any, color: Tuple[str, str] ) -> Tuple[ List[NodeGraph], List[EdgeGraph] ]: + +def build_nodes_and_edges( + publications: any, color: Tuple[str, str] +) -> Tuple[List[NodeGraph], List[EdgeGraph]]: all_nodes: dict[UUID, Person] = {} nodes: List[NodeGraph] = [] edges: List[EdgeGraph] = [] - publications_by_person = count_publications_by_person( publications ) + publications_by_person = count_publications_by_person(publications) max_publications = max(publications_by_person.values()) - + for publication in publications: # save nodes for author in publication.authors: if author.uuid not in all_nodes: nn = NodeGraph( - author, - size=25 + 5*publications_by_person[author.uuid], + author, + size=25 + 5 * publications_by_person[author.uuid], color=darken_color( - color=select_color( author, color, '#ACDBC9' ), - number=publications_by_person[author.uuid], - range=2*max_publications - ) + color=select_color(author, color, "#ACDBC9"), + number=publications_by_person[author.uuid], + range=2 * max_publications, + ), ) - all_nodes[ author.uuid ] = nn - nodes.append( nn ) + all_nodes[author.uuid] = nn + nodes.append(nn) - # save edges - for i in range( len(publication.authors) ): + # save edges + for i in range(len(publication.authors)): author = publication.authors[i] for j in range(i + 1, len(publication.authors)): author_2 = publication.authors[j] - edges.append(EdgeGraph(all_nodes[author.uuid], all_nodes[author_2.uuid], publication)) + edges.append( + EdgeGraph( + all_nodes[author.uuid], all_nodes[author_2.uuid], publication + ) + ) del all_nodes return (nodes, edges) -def build_publications_graph( publications: List[any], color: Tuple[str, str], width = 900, height = 700 ) -> any: - nodesGraph, edgesGraph = build_nodes_and_edges( publications, color ) - publ_by_person = count_publications_by_person( publications ) + +def build_publications_graph( + publications: List[any], color: Tuple[str, str], width=900, height=700 +) -> any: + nodesGraph, edgesGraph = build_nodes_and_edges(publications, color) + publ_by_person = count_publications_by_person(publications) nodes: List[Node] = [] edges: List[Edge] = [] - + for node in nodesGraph: publ = f"{publ_by_person[ node.info.uuid ]} {'publicación' if publ_by_person[node.info.uuid] == 1 else 'publicaciones'}" - nodes.append(Node( - id=f"{node.info.uuid}", - title=f"{node.info.name}\n{publ}", - label=node.info.name, - color=node.color, - size=node.size - )) - + nodes.append( + Node( + id=f"{node.info.uuid}", + title=f"{node.info.name}\n{publ}", + label=node.info.name, + color=node.color, + size=node.size, + ) + ) + for edge in edgesGraph: - count_pub = count_publications_between_two_persons( publications, edge.source.info, edge.target.info ) - edges.append(Edge( - source=f"{edge.source.info.uuid}", - label=f"{count_pub} {'publicación' if count_pub == 1 else 'publicaciones'}", - target=f"{edge.target.info.uuid}", - color=edge.color, - directed=False, - collapsible=False - )) - edges.append(Edge( - source=f"{edge.target.info.uuid}", - target=f"{edge.source.info.uuid}", - label="", - color=edge.color, - directed=False, - collapsible=False - )) - - config = Config( width=width, height=height ) - return nodes, edges, agraph(nodes=nodes, edges=edges, config=config) + count_pub = count_publications_between_two_persons( + publications, edge.source.info, edge.target.info + ) + edges.append( + Edge( + source=f"{edge.source.info.uuid}", + label=f"{count_pub} {'publicación' if count_pub == 1 else 'publicaciones'}", + target=f"{edge.target.info.uuid}", + color=edge.color, + directed=False, + collapsible=False, + ) + ) + edges.append( + Edge( + source=f"{edge.target.info.uuid}", + target=f"{edge.source.info.uuid}", + label="", + color=edge.color, + directed=False, + collapsible=False, + ) + ) + config = Config(width=width, height=height) + return nodes, edges, agraph(nodes=nodes, edges=edges, config=config) diff --git a/dashboard/modules/utils.py b/dashboard/modules/utils.py index 8c0161d..44ec88a 100644 --- a/dashboard/modules/utils.py +++ b/dashboard/modules/utils.py @@ -1,14 +1,16 @@ -from random import randint import colorsys +from random import randint +from typing import Tuple +from uuid import UUID from models import Person -from uuid import UUID -from typing import Tuple + def generate_widget_key() -> str: return str(randint(0, 1000000)) -def count_theses_by_advisor( theses ) -> dict: + +def count_theses_by_advisor(theses) -> dict: advisors = {} for thesis in theses: @@ -19,40 +21,51 @@ def count_theses_by_advisor( theses ) -> dict: return advisors -def count_theses_between_two_advisors( theses, advisor_1, advisor_2 ) -> int: + +def count_theses_between_two_advisors(theses, advisor_1, advisor_2) -> int: count = 0 for thesis in theses: if advisor_1 in thesis.advisors and advisor_2 in thesis.advisors: count += 1 return count -def count_publications_by_person( publications ) -> dict: - count: dict[ UUID, int ] = {} - + +def count_publications_by_person(publications) -> dict: + count: dict[UUID, int] = {} + for publication in publications: for author in publication.authors: - if author.uuid not in count: - count[ author.uuid ] = 0 - count[ author.uuid ] += 1 + if author.uuid not in count: + count[author.uuid] = 0 + count[author.uuid] += 1 return count -def count_publications_between_two_persons( publications, person_1: Person, person_2: Person ) -> int: + +def count_publications_between_two_persons( + publications, person_1: Person, person_2: Person +) -> int: count = 0 for publication in publications: if person_1 in publication.authors and person_2 in publication.authors: count += 1 return count -def darken_color(color:str, number:int, range:int) -> str: - color = color.lstrip('#') - - h, l, s = colorsys.rgb_to_hls(*[int(color[i:i+2], 16)/255 for i in (0, 2, 4)]) + +def darken_color(color: str, number: int, range: int) -> str: + color = color.lstrip("#") + + h, l, s = colorsys.rgb_to_hls(*[int(color[i : i + 2], 16) / 255 for i in (0, 2, 4)]) l = max(0.1, l - (number / range)) - return '#%02x%02x%02x' % tuple(int(i*255) for i in colorsys.hls_to_rgb(h, l, s)) + return "#%02x%02x%02x" % tuple(int(i * 255) for i in colorsys.hls_to_rgb(h, l, s)) + -def select_color( person: Person, color: Tuple[str, str], default_color ) -> str: +def select_color(person: Person, color: Tuple[str, str], default_color) -> str: inst, cc = color - if person.institution == inst or person.department == inst or person.faculty == inst: + if ( + person.institution == inst + or person.department == inst + or person.faculty == inst + ): return cc - return default_color \ No newline at end of file + return default_color diff --git "a/dashboard/pages/01_\360\237\221\245_personal.py" "b/dashboard/pages/01_\360\237\221\245_personal.py" index 1a063d4..eeea43c 100644 --- "a/dashboard/pages/01_\360\237\221\245_personal.py" +++ "b/dashboard/pages/01_\360\237\221\245_personal.py" @@ -9,4 +9,4 @@ ), ) -router.start() \ No newline at end of file +router.start() diff --git "a/dashboard/pages/02_\360\237\223\235_docencia.py" "b/dashboard/pages/02_\360\237\223\235_docencia.py" index 6bc5cd4..bd75207 100644 --- "a/dashboard/pages/02_\360\237\223\235_docencia.py" +++ "b/dashboard/pages/02_\360\237\223\235_docencia.py" @@ -9,4 +9,4 @@ ), ) -router.start() \ No newline at end of file +router.start() diff --git "a/dashboard/pages/03_\360\237\221\245_grupos.py" "b/dashboard/pages/03_\360\237\221\245_grupos.py" index 2907a48..96c4ff8 100644 --- "a/dashboard/pages/03_\360\237\221\245_grupos.py" +++ "b/dashboard/pages/03_\360\237\221\245_grupos.py" @@ -9,4 +9,4 @@ ), ) -router.start() \ No newline at end of file +router.start() diff --git "a/dashboard/pages/04_\360\237\216\223_tesis.py" "b/dashboard/pages/04_\360\237\216\223_tesis.py" index 0af7573..da7ce59 100644 --- "a/dashboard/pages/04_\360\237\216\223_tesis.py" +++ "b/dashboard/pages/04_\360\237\216\223_tesis.py" @@ -9,4 +9,4 @@ ), ) -router.start() \ No newline at end of file +router.start() diff --git "a/dashboard/pages/05_\360\237\223\232_publicaciones.py" "b/dashboard/pages/05_\360\237\223\232_publicaciones.py" index a28b357..3e49821 100644 --- "a/dashboard/pages/05_\360\237\223\232_publicaciones.py" +++ "b/dashboard/pages/05_\360\237\223\232_publicaciones.py" @@ -10,28 +10,6 @@ from pages.publications_pages.papers import papers_page from pages.publications_pages.presentations import presentations_page - -class ControlledSectionModel: ... - - -class Page(abc.ABC): - def __init__(self, url: str, section_model: ControlledSectionModel): - self.url = url - self.section_model: Optional[ControlledSectionModel] = section_model - - # This is modified when the router is composed - self.full_url = url - - @property - def user_can_open(self): - if auth.in_admin_session or self.section_model is None: - return True - - @abc.abstractmethod - def build(self, router: PageRouter, **params): - pass - - # TODO: Only build router if it is not stored in session router = PageRouter( "publications", diff --git "a/dashboard/pages/06_\342\232\227\357\270\217_proyectos.py" "b/dashboard/pages/06_\342\232\227\357\270\217_proyectos.py" index 5f20413..ae800b6 100644 --- "a/dashboard/pages/06_\342\232\227\357\270\217_proyectos.py" +++ "b/dashboard/pages/06_\342\232\227\357\270\217_proyectos.py" @@ -9,4 +9,4 @@ ), ) -router.start() \ No newline at end of file +router.start() diff --git "a/dashboard/pages/07_\360\237\217\206_premios.py" "b/dashboard/pages/07_\360\237\217\206_premios.py" index 292043c..dd6f2e4 100644 --- "a/dashboard/pages/07_\360\237\217\206_premios.py" +++ "b/dashboard/pages/07_\360\237\217\206_premios.py" @@ -9,4 +9,4 @@ ), ) -router.start() \ No newline at end of file +router.start() diff --git "a/dashboard/pages/08_\360\237\252\221_expertos.py" "b/dashboard/pages/08_\360\237\252\221_expertos.py" index b6adcaa..1885969 100644 --- "a/dashboard/pages/08_\360\237\252\221_expertos.py" +++ "b/dashboard/pages/08_\360\237\252\221_expertos.py" @@ -9,4 +9,4 @@ ), ) -router.start() \ No newline at end of file +router.start() diff --git "a/dashboard/pages/09_\360\237\223\210_reportes.py" "b/dashboard/pages/09_\360\237\223\210_reportes.py" index b62cba1..c991d28 100644 --- "a/dashboard/pages/09_\360\237\223\210_reportes.py" +++ "b/dashboard/pages/09_\360\237\223\210_reportes.py" @@ -9,4 +9,4 @@ ), ) -router.start() \ No newline at end of file +router.start() diff --git "a/dashboard/pages/99_\360\237\233\240\357\270\217_admin.py" "b/dashboard/pages/99_\360\237\233\240\357\270\217_admin.py" index df4992c..edff0f8 100644 --- "a/dashboard/pages/99_\360\237\233\240\357\270\217_admin.py" +++ "b/dashboard/pages/99_\360\237\233\240\357\270\217_admin.py" @@ -9,4 +9,4 @@ ), ) -router.start() \ No newline at end of file +router.start() diff --git a/dashboard/pages/admin_pages/home.py b/dashboard/pages/admin_pages/home.py index 1747e1b..7cee3b1 100644 --- a/dashboard/pages/admin_pages/home.py +++ b/dashboard/pages/admin_pages/home.py @@ -22,7 +22,6 @@ def admin_page(router: PageRouter, **params): (database,) = st.tabs(["🗄️ Base de datos"]) - def format_bytes(n_bytes: int) -> str: if n_bytes > 1e6: return f"{round(n_bytes * 1e-6, 2)} MB" @@ -30,7 +29,6 @@ def format_bytes(n_bytes: int) -> str: return f"{round(n_bytes * 1e-3, 2)} kB" return f"{n_bytes} B" - with database: general_stats, tools_exp, tools_imp, tools_del = st.columns([2, 1, 1, 1]) stats = {model: model.stats() for model in collection_names.keys()} diff --git a/dashboard/pages/dashboard_pages/registration.py b/dashboard/pages/dashboard_pages/registration.py index 69ddbe5..c3978d0 100644 --- a/dashboard/pages/dashboard_pages/registration.py +++ b/dashboard/pages/dashboard_pages/registration.py @@ -13,7 +13,6 @@ def registration_page(router: PageRouter, token: str = None, **params): router.page_header("Registro") - # Verify token email = auth.verify_token(token) if email is None: diff --git a/dashboard/pages/docencia_pages/home.py b/dashboard/pages/docencia_pages/home.py index 18d6f72..6c3c4b4 100644 --- a/dashboard/pages/docencia_pages/home.py +++ b/dashboard/pages/docencia_pages/home.py @@ -7,8 +7,9 @@ def docencia_page(router: PageRouter, **params): - - st.set_page_config(page_title="MatCom Dashboard - Docencia", page_icon="📝", layout="wide") + st.set_page_config( + page_title="MatCom Dashboard - Docencia", page_icon="📝", layout="wide" + ) router.page_header("Docencia") @@ -17,7 +18,6 @@ def docencia_page(router: PageRouter, **params): with subjects_tab: if auth.is_user_logged(): with st.expander("⭐ Crear nueva asignatura"): - cols = st.columns([2, 2, 1, 1]) subject = cols[0].text_input("Nombre de la asignatura") career = cols[1].selectbox( @@ -41,12 +41,13 @@ def docencia_page(router: PageRouter, **params): subjects = [] - for subject in sorted(Subject.all(), key=lambda s: (s.year, s.semester, s.subject)): + for subject in sorted( + Subject.all(), key=lambda s: (s.year, s.semester, s.subject) + ): subjects.append(subject.encode()) st.dataframe(subjects) - with classes_tab: if auth.is_user_logged(): with st.expander("📝 Crear nueva entrada"): diff --git a/dashboard/pages/expertos_pages/home.py b/dashboard/pages/expertos_pages/home.py index 4422df6..fedb7cd 100644 --- a/dashboard/pages/expertos_pages/home.py +++ b/dashboard/pages/expertos_pages/home.py @@ -3,6 +3,7 @@ def expertos_page(router: PageRouter, **params): - st.set_page_config(page_title="MatCom Dashboard - Consejos Expertos", page_icon="🪑", layout="wide") + st.set_page_config( + page_title="MatCom Dashboard - Consejos Expertos", page_icon="🪑", layout="wide" + ) router.page_header("Expertos") - diff --git a/dashboard/pages/grupos_pages/home.py b/dashboard/pages/grupos_pages/home.py index 86ae448..3bfa805 100644 --- a/dashboard/pages/grupos_pages/home.py +++ b/dashboard/pages/grupos_pages/home.py @@ -5,18 +5,20 @@ def grupos_page(router: PageRouter, **params): - st.set_page_config(page_title="MatCom Dashboard - Grupos de Investigación",page_icon="👥",layout="wide",) + st.set_page_config( + page_title="MatCom Dashboard - Grupos de Investigación", + page_icon="👥", + layout="wide", + ) router.page_header("Grupos de Investigación") list_view, create_view = st.tabs(["👥 Listado de grupos", "📝 Crear o editar"]) - groups = ResearchGroup.all() people = Person.all() people.sort(key=lambda p: p.name) - with create_view: if auth.is_user_logged(): if ( @@ -34,7 +36,9 @@ def grupos_page(router: PageRouter, **params): format_func=lambda t: t.name, ) else: - group = ResearchGroup(name="", members=[], collaborators=[], keywords=[]) + group = ResearchGroup( + name="", members=[], collaborators=[], keywords=[] + ) if group: group.name = st.text_input("Nombre", key="group_name", value=group.name) @@ -68,7 +72,9 @@ def grupos_page(router: PageRouter, **params): group.save() st.success("Información guardad con éxito") else: - st.error("Acceso de solo lectura. Vaya a la página principal para loguearse.") + st.error( + "Acceso de solo lectura. Vaya a la página principal para loguearse." + ) with list_view: for group in groups: @@ -77,7 +83,9 @@ def grupos_page(router: PageRouter, **params): with left: st.write(f"#### {group.name}") - st.write("**Líneas de investigación:** " + "; ".join(group.keywords)) + st.write( + "**Líneas de investigación:** " + "; ".join(group.keywords) + ) st.write(f"**Coordinador**: {group.head.name}") with mid: @@ -95,6 +103,8 @@ def grupos_page(router: PageRouter, **params): "**Colaboradores:**\n" + "\n".join( f"- {p.name}" - for p in sorted(group.collaborators, key=lambda p: p.name) + for p in sorted( + group.collaborators, key=lambda p: p.name + ) ) ) diff --git a/dashboard/pages/personal_pages/home.py b/dashboard/pages/personal_pages/home.py index 622860f..ca9782a 100644 --- a/dashboard/pages/personal_pages/home.py +++ b/dashboard/pages/personal_pages/home.py @@ -6,10 +6,11 @@ def personal_page(router: PageRouter, **params): - st.set_page_config(page_title="MatCom Dashboard - Personal", page_icon="👤", layout="wide") + st.set_page_config( + page_title="MatCom Dashboard - Personal", page_icon="👤", layout="wide" + ) router.page_header("Personal") - people = Person.all() people.sort(key=lambda p: p.name) @@ -54,7 +55,12 @@ def personal_page(router: PageRouter, **params): person.department = st.text_input( "Departamento", key="person_department", value=person.department or "" ) - grades = ["Licenciado", "Ingeniero", "Máster en Ciencias", "Doctor en Ciencias"] + grades = [ + "Licenciado", + "Ingeniero", + "Máster en Ciencias", + "Doctor en Ciencias", + ] person.scientific_grade = st.selectbox( "Grado científico", grades, @@ -85,7 +91,6 @@ def personal_page(router: PageRouter, **params): person.save() st.success("Entrada salvada con éxito.") - people_comp = [] people_appl = [] people_math = [] diff --git a/dashboard/pages/premios_pages/home.py b/dashboard/pages/premios_pages/home.py index 008d73f..c5d2f0b 100644 --- a/dashboard/pages/premios_pages/home.py +++ b/dashboard/pages/premios_pages/home.py @@ -7,14 +7,15 @@ def premios_page(router: PageRouter, **params): - st.set_page_config(page_title="MatCom Dashboard - Premios", page_icon="🏆", layout="wide") + st.set_page_config( + page_title="MatCom Dashboard - Premios", page_icon="🏆", layout="wide" + ) router.page_header("Premios") list_view, create_view, edit_view = st.tabs( ["🏆 Listado de premios", "⭐ Crear nuevo premio", "📝 Editar premio"] ) - def save_award(award: Award, prefix): award.save() @@ -25,7 +26,6 @@ def save_award(award: Award, prefix): del st.session_state.current_award st.success("Premio guardado con éxito") - with create_view: if auth.is_user_logged(): if "current_award" in st.session_state: @@ -41,8 +41,9 @@ def save_award(award: Award, prefix): else: st.warning("⚠️ Complete la información obligatoria, marcada con 🔹") else: - st.error("Acceso de solo lectura. Vaya a la página principal para loguearse.") - + st.error( + "Acceso de solo lectura. Vaya a la página principal para loguearse." + ) with list_view: awards = Award.all() diff --git a/dashboard/pages/profile_pages/home.py b/dashboard/pages/profile_pages/home.py index 42ef928..3e3b1eb 100644 --- a/dashboard/pages/profile_pages/home.py +++ b/dashboard/pages/profile_pages/home.py @@ -18,7 +18,7 @@ def profile_page(router: PageRouter, **params): if not persons: st.error("Tu cuenta no está registrada") st.stop() - + person = persons[0] c1, c2 = st.columns([1, 5]) diff --git a/dashboard/pages/proyectos_pages/home.py b/dashboard/pages/proyectos_pages/home.py index 3c54462..411ea93 100644 --- a/dashboard/pages/proyectos_pages/home.py +++ b/dashboard/pages/proyectos_pages/home.py @@ -1,15 +1,17 @@ -import streamlit as st -import auth from uuid import uuid4 + +import auth +import streamlit as st from models import Project from page_router import PageRouter def proyectos_page(router: PageRouter, **params): - st.set_page_config(page_title="MatCom Dashboard - Proyectos", page_icon="⚗️", layout="wide") + st.set_page_config( + page_title="MatCom Dashboard - Proyectos", page_icon="⚗️", layout="wide" + ) router.page_header("Proyectos") - def save_project(project: Project, prefix): project.save() @@ -20,14 +22,12 @@ def save_project(project: Project, prefix): del st.session_state.current_project st.success("Proyecto guardado con éxito") - st.title("⚗️ Proyectos") list_view, create_view, edit_view = st.tabs( ["⚗️ Listado de proyectos", "⭐ Crear nuevo proyecto", "📝 Editar proyecto"] ) - with create_view: if auth.is_user_logged(): if "current_project" in st.session_state: @@ -43,20 +43,21 @@ def save_project(project: Project, prefix): else: st.warning("⚠️ Complete la información obligatoria, marcada con 🔹") else: - st.error("Acceso de solo lectura. Vaya a la página principal para loguearse.") - + st.error( + "Acceso de solo lectura. Vaya a la página principal para loguearse." + ) with edit_view: if auth.is_user_logged(): pass else: - st.error("Acceso de solo lectura. Vaya a la página principal para loguearse.") - + st.error( + "Acceso de solo lectura. Vaya a la página principal para loguearse." + ) projects = Project.all() projects.sort(key=lambda p: p.title) - with list_view: for project in projects: with st.expander( @@ -81,7 +82,9 @@ def save_project(project: Project, prefix): ) with right: - st.write(f"##### Entidad ejecutora principal:\n" + project.main_entity) + st.write( + f"##### Entidad ejecutora principal:\n" + project.main_entity + ) st.write("---") st.write( f"##### Entidades participantes adicionales:\n" diff --git a/dashboard/pages/publications_pages/books_and_chapters.py b/dashboard/pages/publications_pages/books_and_chapters.py index 25b5eb6..f6984a1 100644 --- a/dashboard/pages/publications_pages/books_and_chapters.py +++ b/dashboard/pages/publications_pages/books_and_chapters.py @@ -6,7 +6,9 @@ def books_and_chapters_page(router, **params): - st.set_page_config(page_title="MatCom Dashboard - Libros y Capítulos de Libros", layout="wide") + st.set_page_config( + page_title="MatCom Dashboard - Libros y Capítulos de Libros", layout="wide" + ) router.page_header("📕 Libros y Capítulos de Libros") year = st.sidebar.selectbox("Año", [2020, 2021, 2022], index=2) diff --git a/dashboard/pages/reportes_pages/home.py b/dashboard/pages/reportes_pages/home.py index 442485f..132c28c 100644 --- a/dashboard/pages/reportes_pages/home.py +++ b/dashboard/pages/reportes_pages/home.py @@ -2,16 +2,17 @@ import streamlit as st from models import Person, ResearchGroup -from reports import group_report, personal_report, research_balance -from streamlit.elements import select_slider from page_router import PageRouter +from pages.reportes_pages.reports import group_report, personal_report, research_balance +from streamlit.elements import select_slider def reportes_page(router: PageRouter, **params): - st.set_page_config(page_title="MatCom Dashboard - Reportes", page_icon="📈", layout="wide") + st.set_page_config( + page_title="MatCom Dashboard - Reportes", page_icon="📈", layout="wide" + ) router.page_header("Reportes") - balance, posgrado, personal, group = st.tabs( [ "⚗️ Balance de Investigación", @@ -27,7 +28,6 @@ def reportes_page(router: PageRouter, **params): groups = ResearchGroup.all() groups.sort(key=lambda g: g.name) - with balance: today = datetime.date.today() @@ -41,7 +41,6 @@ def reportes_page(router: PageRouter, **params): for line in research_balance(start_date, end_date): st.write(line) - with personal: person = st.selectbox("Seleccione la persona", people) diff --git a/dashboard/reports.py b/dashboard/pages/reportes_pages/reports.py similarity index 100% rename from dashboard/reports.py rename to dashboard/pages/reportes_pages/reports.py diff --git a/dashboard/pages/tesis_pages/home.py b/dashboard/pages/tesis_pages/home.py index b36b4ba..0e07d3d 100644 --- a/dashboard/pages/tesis_pages/home.py +++ b/dashboard/pages/tesis_pages/home.py @@ -14,11 +14,14 @@ def tesis_page(router: PageRouter, **params): - st.set_page_config(page_title="MatCom Dashboard - Tesis", page_icon="🎓", layout="wide") + st.set_page_config( + page_title="MatCom Dashboard - Tesis", page_icon="🎓", layout="wide" + ) router.page_header("Tesis") - - listing, create, details = st.tabs(["📃 Listado", "➕ Crear nueva Tesis", "📄 Detalles"]) + listing, create, details = st.tabs( + ["📃 Listado", "➕ Crear nueva Tesis", "📄 Detalles"] + ) theses: List[Thesis] = Thesis.all() @@ -112,7 +115,9 @@ def tesis_page(router: PageRouter, **params): if "file_uploader_key" not in st.session_state: st.session_state["file_uploader_key"] = generate_widget_key() pdf = st.file_uploader( - "📤 Subir Tesis", type="pdf", key=st.session_state["file_uploader_key"] + "📤 Subir Tesis", + type="pdf", + key=st.session_state["file_uploader_key"], ) with right: diff --git "a/dashboard/\342\255\220_dashboard.py" "b/dashboard/\342\255\220_dashboard.py" index 4e7dedc..4623f3b 100644 --- "a/dashboard/\342\255\220_dashboard.py" +++ "b/dashboard/\342\255\220_dashboard.py" @@ -14,17 +14,6 @@ def dashboard(router: PageRouter, **params): left, right = st.columns(2) with right: - # if not auth.is_user_logged(): - # st.info( - # """ - # Si usted es claustro de la facultad y desea modificar los datos, - # introduzca la contraseña correspondiente. De lo contrario, puede leer - # los datos pero no modificar. - - # Si usted cree que debería tener acceso, contacte con - # [@apiad](https://t.me/apiad) en Telegram.""" - # ) - auth.authenticate() if auth.is_user_logged(): @@ -46,11 +35,7 @@ def dashboard(router: PageRouter, **params): Route( url="signup", builder=registration_page, - redirect=lambda **_: ( - "home" - if auth.is_user_logged() - else None - ), + redirect=lambda **_: ("home" if auth.is_user_logged() else None), ) ], ),