Skip to content
Merged
Show file tree
Hide file tree
Changes from 37 commits
Commits
Show all changes
38 commits
Select commit Hold shift + click to select a range
6e54b65
feat(web): indicador visual de carregamento ao validar pacote
Rossi-Luciano Jul 30, 2026
3953a4e
feat(web): identidade visual e layout mais cuidados na tela principal
Rossi-Luciano Jul 30, 2026
c7741fc
style(web): envolve tabela de historico em table-wrap e usa badge de …
Rossi-Luciano Jul 30, 2026
09bb877
feat(web): calcula rotulo curto para cada PDF do historico
Rossi-Luciano Jul 30, 2026
61dd18c
style(web): estilo de "chip" para os links de PDF do historico
Rossi-Luciano Jul 30, 2026
9877da7
feat(web): renderiza PDFs do historico como chips com rotulo curto
Rossi-Luciano Jul 30, 2026
b8bfaa0
fix(web): remove microssegundos da data exibida no historico
Rossi-Luciano Jul 30, 2026
09fabd3
fix(web): preserva q/status/page_size/page ao redirecionar apos validar
Rossi-Luciano Jul 30, 2026
6f2e385
fix(web): formulario de validar envia a querystring atual da pagina
Rossi-Luciano Jul 30, 2026
39878c2
feat(web): calcula janela de paginas pra paginacao numerada
Rossi-Luciano Jul 30, 2026
033ede2
feat(web): paginacao numerada no historico, estilo Django
Rossi-Luciano Jul 30, 2026
bd9af36
style(web): estilo visual da paginacao numerada
Rossi-Luciano Jul 30, 2026
5a70a79
refactor(version): extrai is_running_from_source() reutilizavel
Rossi-Luciano Jul 30, 2026
0fc9052
fix(web): rodape para de confiar em build_info.py rodando do codigo-f…
Rossi-Luciano Jul 30, 2026
0a085f1
feat(web): abas pra "Artigos Considerados" e "Pacotes validados"
Rossi-Luciano Jul 30, 2026
66a311b
style(web): generaliza classes de chip pra reuso em CSV/HTML/PDF
Rossi-Luciano Jul 30, 2026
4727f45
feat(web): consolida CSV/HTML/PDF numa unica coluna "Ações"
Rossi-Luciano Jul 30, 2026
6088de2
i18n(web): traduz as strings novas da issue #36 para en/es
Rossi-Luciano Jul 30, 2026
c00a5a3
Merge branch 'main' into feature/issue-36-melhorias-ui-ux
Rossi-Luciano Jul 31, 2026
20fce97
feat(web): reconstroi o relatorio HTML com a identidade visual do SciELO
Rossi-Luciano Jul 31, 2026
180d49b
i18n(web): traduz as strings novas do relatorio redesenhado para en/es
Rossi-Luciano Jul 31, 2026
fcc8075
fix(packaging): gera build_info.py real no build Linux
Rossi-Luciano Jul 31, 2026
5cc3028
fix(web): corrige rotulo de PDF por prefixo e formato de data no hist…
Rossi-Luciano Jul 31, 2026
21d5816
i18n(web): usa msgid em pt-BR pra coluna de excecoes do historico
Rossi-Luciano Jul 31, 2026
4510e7a
style(web): encurta e reordena as abas de Artigos/Pacotes
Rossi-Luciano Jul 31, 2026
dd6afbd
i18n(web): atualiza catalogo pt pros msgids revisados no PR #37
Rossi-Luciano Jul 31, 2026
32941ed
i18n(web): traduz os msgids revisados no PR #37 pro catalogo en
Rossi-Luciano Jul 31, 2026
0943824
i18n(web): traduz os msgids revisados no PR #37 pro catalogo es
Rossi-Luciano Jul 31, 2026
133b292
fix(web): adiciona checagem defensiva platform.system() no rodape
Rossi-Luciano Aug 2, 2026
36406fd
feat(packaging): cria generate_build_info.ps1 pro build Windows
Rossi-Luciano Aug 2, 2026
c43a083
fix(packaging): chama generate_build_info.ps1 no build Windows
Rossi-Luciano Aug 2, 2026
24fd5f2
test(web): cobre get_footer_build_label com build_info desatualizado
Rossi-Luciano Aug 2, 2026
94fc638
feat(db): adiciona list_articles/count_articles/get_package_name
Rossi-Luciano Aug 2, 2026
43b0294
test(db): cobre list_articles/count_articles
Rossi-Luciano Aug 2, 2026
17c172a
feat(web): adiciona /articles-list e desacopla a aba Artigos de lates…
Rossi-Luciano Aug 2, 2026
5aadd55
feat(web): cria partial da listagem de artigos
Rossi-Luciano Aug 2, 2026
b6c2e54
feat(web): abas Pacotes/Artigos sempre visiveis com filtro proprio de…
Rossi-Luciano Aug 2, 2026
1c2fab8
Merge remote-tracking branch 'origin/main' into feature/issue-36-melh…
Rossi-Luciano Aug 3, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions spsvalidator/packaging/build_linux.sh
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ cd "$ROOT_DIR"
python -m pip install -e ".[dev]"
python -m pip install pyinstaller
pybabel compile -d src/spsvalidator/translations
bash packaging/generate_build_info.sh
pyinstaller --noconfirm --windowed \
--name spsvalidator \
--icon src/spsvalidator/web/static/img/icon.png \
Expand Down
1 change: 1 addition & 0 deletions spsvalidator/packaging/build_windows.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ Set-Location $RootDir
python -m pip install -e ".[dev]"
python -m pip install pyinstaller
pybabel compile -d src/spsvalidator/translations
& "$PSScriptRoot\generate_build_info.ps1"
pyinstaller --noconfirm --windowed `
--name spsvalidator `
--icon src/spsvalidator/web/static/img/icon.png `
Expand Down
14 changes: 14 additions & 0 deletions spsvalidator/packaging/generate_build_info.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
Set-StrictMode -Version Latest
$ErrorActionPreference = "Stop"

$RootDir = Split-Path -Path $PSScriptRoot -Parent
$TargetPath = Join-Path $RootDir "src\spsvalidator\build_info.py"
Set-Location $RootDir

$AppVersion = python -c "import tomllib; print(tomllib.load(open('pyproject.toml', 'rb'))['project']['version'])"

@"
APP_VERSION = "$AppVersion"
BUILD_MACOS_VERSION = "development"
BUILD_PLATFORM = "Windows"
"@ | Set-Content -Path $TargetPath -Encoding UTF8
5 changes: 4 additions & 1 deletion spsvalidator/src/spsvalidator/build_metadata.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,15 @@
from flask_babel import gettext

from spsvalidator import build_info
from spsvalidator.version import is_running_from_source


def get_footer_build_label() -> str:
if (
build_info.BUILD_MACOS_VERSION != "development"
not is_running_from_source()
and build_info.BUILD_MACOS_VERSION != "development"
and build_info.BUILD_PLATFORM == "macOS"
and platform.system() == "Darwin"
):
return gettext(
"Compilado para macOS %(version)s",
Expand Down
103 changes: 103 additions & 0 deletions spsvalidator/src/spsvalidator/db/repository.py
Original file line number Diff line number Diff line change
Expand Up @@ -175,6 +175,109 @@ def count_validations(
return int(total)


def _articles_filter_clause(
name_query: str | None,
doi_query: str | None,
pid_query: str | None,
status: str | None,
history_id: str | None,
) -> tuple[str, list]:
conditions = []
params: list = []
if name_query:
conditions.append("LOWER(package_validation_history.package_name) LIKE LOWER(?)")
params.append(f"%{name_query}%")
if doi_query:
conditions.append("LOWER(package_article_snapshot.doi) LIKE LOWER(?)")
params.append(f"%{doi_query}%")
if pid_query:
conditions.append("LOWER(package_article_snapshot.pid) LIKE LOWER(?)")
params.append(f"%{pid_query}%")
if status:
conditions.append("package_article_snapshot.article_status = ?")
params.append(status)
if history_id:
conditions.append("package_article_snapshot.history_id = ?")
params.append(history_id)
where_clause = " WHERE " + " AND ".join(conditions) if conditions else ""
return where_clause, params


def list_articles(
db_path: str,
name_query: str | None = None,
doi_query: str | None = None,
pid_query: str | None = None,
status: str | None = None,
history_id: str | None = None,
limit: int | None = None,
offset: int = 0,
) -> list[dict]:
where_clause, params = _articles_filter_clause(
name_query, doi_query, pid_query, status, history_id
)
sql = f"""
SELECT
package_article_snapshot.id,
package_article_snapshot.history_id,
package_article_snapshot.xml_path,
package_article_snapshot.title,
package_article_snapshot.authors_text,
package_article_snapshot.doi,
package_article_snapshot.pid,
package_article_snapshot.article_status,
package_article_snapshot.issue_count,
package_validation_history.package_name,
package_validation_history.validated_at
FROM package_article_snapshot
JOIN package_validation_history
ON package_validation_history.id = package_article_snapshot.history_id
{where_clause}
ORDER BY datetime(package_validation_history.validated_at) DESC,
package_article_snapshot.xml_path
"""
if limit is not None:
sql += " LIMIT ? OFFSET ?"
params = params + [limit, offset]

with sqlite3.connect(db_path) as connection:
connection.row_factory = sqlite3.Row
rows = connection.execute(sql, params).fetchall()
return [dict(row) for row in rows]


def count_articles(
db_path: str,
name_query: str | None = None,
doi_query: str | None = None,
pid_query: str | None = None,
status: str | None = None,
history_id: str | None = None,
) -> int:
where_clause, params = _articles_filter_clause(
name_query, doi_query, pid_query, status, history_id
)
sql = f"""
SELECT COUNT(*)
FROM package_article_snapshot
JOIN package_validation_history
ON package_validation_history.id = package_article_snapshot.history_id
{where_clause}
"""
with sqlite3.connect(db_path) as connection:
total = connection.execute(sql, params).fetchone()[0]
return int(total)


def get_package_name(db_path: str, history_id: str) -> str | None:
with sqlite3.connect(db_path) as connection:
row = connection.execute(
"SELECT package_name FROM package_validation_history WHERE id = ?",
(history_id,),
).fetchone()
return row[0] if row else None


def get_validation_details(db_path: str, history_id: str) -> dict | None:
with sqlite3.connect(db_path) as connection:
connection.row_factory = sqlite3.Row
Expand Down
Loading