From 557095014bdf4bcc56cfa323259f713f93275476 Mon Sep 17 00:00:00 2001 From: Samuel Veiga Rangel Date: Fri, 15 Nov 2024 12:11:50 -0300 Subject: [PATCH 1/3] Atualiza dependencias --- requirements.dev.txt | 2 +- requirements.txt | 152 +++++++++++++++++++++---------------------- 2 files changed, 77 insertions(+), 77 deletions(-) diff --git a/requirements.dev.txt b/requirements.dev.txt index 47c1c73d5..82727db24 100644 --- a/requirements.dev.txt +++ b/requirements.dev.txt @@ -1,4 +1,4 @@ -Flask-DebugToolbar==0.13.1 +Flask-DebugToolbar==0.14.1 Flask-Testing==0.8.1 mock==5.0.1 coverage==7.0.5 diff --git a/requirements.txt b/requirements.txt index b09596875..f518ac656 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,99 +1,99 @@ -alembic==1.9.2 -arrow==1.2.3 -async-timeout==4.0.2 -Babel==2.11.0 -beautifulsoup4==4.11.1 -blinker==1.5 -cachelib==0.9.0 -cachetools==5.2.1 -certifi==2022.12.7 -chardet==5.1.0 -charset-normalizer==3.0.1 +alembic==1.14.0 +# arrow==1.3.0 +# async-timeout==4.0.2 # remover +Babel==2.16.0 +beautifulsoup4==4.12.3 +# blinker==1.9.0 +cachelib==0.9.0 # flask-caching 2.3.0 depends on cachelib<0.10.0 and >=0.9.0 +cachetools==5.5.0 +# certifi==2024.8.30 +# chardet==5.2.0 +# charset-normalizer==3.4.0 citeproc-py==0.6.0 citeproc-py-styles==0.1.3 -click==8.1.3 -colorama==0.4.6 -croniter==1.3.8 +click==8.1.7 +# colorama==0.4.6 +# croniter==5.0.1 cssmin==0.2.0 -distlib==0.3.6 -dnspython==2.3.0 -elastic-apm==6.13.2 -email-validator==1.3.0 -feedparser==6.0.10 -feedwerk==1.1.0 -filelock==3.9.0 -Flask==2.2.2 -Flask-Admin==1.6.0 -Flask-BabelEx==0.9.4 -Flask-Caching==2.0.2 +distlib==0.3.9 +dnspython==2.7.0 +elastic-apm==6.23.0 +# email-validator==2.2.0 +feedparser==6.0.11 +feedwerk==1.2.0 +filelock==3.16.1 +Flask==3.0.0 +flask-admin==2.0.0a0 +# Flask-BabelEx==0.9.4 +flask-babel==4.0.0 +Flask-Caching==2.3.0 Flask-HTMLmin==2.2.1 -Flask-Login==0.6.2 -Flask-Mail==0.9.1 -Flask-Migrate==2.6.0 -flask-mongoengine==1.0.0 +Flask-Login==0.6.3 +Flask-Mail==0.10.0 +# Flask-Migrate==2.6.0 +flask-mongoengine2==2.2.0 Flask-Principal==0.4.0 -Flask-Script==2.0.5 -Flask-Security==3.0.0 +# Flask-Script==2.0.6 +# Flask-Security==3.0.0 Flask-SQLAlchemy==3.0.2 -Flask-WTF==1.1.1 -gevent==22.10.2 -greenlet==2.0.1 -gunicorn==20.1.0 +Flask-WTF==1.2.2 +gevent==24.11.1 +greenlet==3.1.1 +gunicorn==23.0.0 htmlmin==0.1.12 -idna==3.4 -itsdangerous==2.1.2 -Jinja2==3.0.0 +idna==3.10 +itsdangerous==2.2.0 +Jinja2==3.1.4 legendarium==2.0.6 lxml==5.3.0 -Mako==1.2.4 -MarkupSafe==2.1.2 -mongoengine==0.25.0 -natsort==8.2.0 +Mako==1.3.6 +MarkupSafe==3.0.2 +mongoengine==0.27.0 +natsort==8.4.0 oauthlib==3.2.2 -packaging==23.0 +packaging==24.2 passlib==1.7.4 -pbr==5.11.1 +pbr==6.1.0 picles.plumber==0.11 -Pillow==9.4.0 -platformdirs==2.6.2 -pluggy==1.0.0 -pymongo==4.3.3 -pyproject_api==1.5.0 +Pillow==11.0.0 +platformdirs==4.3.6 +pluggy==1.5.0 +pymongo==4.8 # flask-mongoengine2 2.2.0 depends on pymongo<=4.8 +pyproject_api==1.8.0 PySocks==1.7.1 -python-dateutil==2.8.2 +python-dateutil==2.9.0.post0 python-editor==1.0.4 -python-slugify==7.0.0 -pytz==2022.7.1 +python-slugify==8.0.4 +pytz==2024.2 raven==6.10.0 -redis==4.4.2 -requests==2.28.2 -requests-oauthlib==1.3.1 -rq==1.12.0 -rq-dashboard==0.6.1 -rq-scheduler==0.11.0 -rq-scheduler-dashboard==0.0.2 +redis==5.2.0 +requests==2.32.3 +requests-oauthlib==1.4.1 # tweepy 4.14.0 depends on requests-oauthlib<2 and >=1.2.0 +rq==2.0.0 +rq-dashboard==0.8.2.2 +rq-scheduler==0.14.0 sgmllib3k==1.0.0 six==1.16.0 -soupsieve==2.3.2.post1 +soupsieve==2.6 speaklater==1.3 -SQLAlchemy==1.4.46 -SQLAlchemy-Utils==0.39.0 +SQLAlchemy==2.0.36 +SQLAlchemy-Utils==0.41.2 text-unidecode==1.3 -tox==4.3.5 -tweepy==4.12.1 +tox==4.23.2 +tweepy==4.14.0 unicodecsv==0.14.1 -Unidecode==1.3.6 -urllib3==1.26.14 -virtualenv==20.17.1 -Werkzeug==2.2.2 -wrapt==1.14.1 -WTForms==3.0.1 -XlsxWriter==3.0.7 -zope.event==4.6 -zope.interface==5.5.2 -tox==4.3.5 -PyJWT==2.8.0 -tenacity==8.2.3 +Unidecode==1.3.8 +urllib3==2.2.3 +virtualenv==20.27.1 +Werkzeug==3.1.3 +wrapt==1.16.0 +WTForms==3.2.1 +XlsxWriter==3.2.0 +zope.event==5.0 +zope.interface==7.1.1 +tox==4.23.2 +PyJWT==2.9.0 +tenacity==9.0.0 -e git+https://git@github.com/scieloorg/opac_schema@v2.8.1#egg=Opac_Schema -e git+https://git@github.com/scieloorg/packtools@4.5.0#egg=packtools -e git+https://github.com/scieloorg/scieloh5m5.git@1.9.5#egg=scieloh5m5 From d2f1bd928500de55d56231ea1dd3dee041fcba44 Mon Sep 17 00:00:00 2001 From: Samuel Veiga Rangel Date: Fri, 15 Nov 2024 12:12:53 -0300 Subject: [PATCH 2/3] Novas importacoes de acordo com o update das dependencias --- opac/tests/test_admin_custom_filters.py | 4 +-- opac/webapp/__init__.py | 20 +++++------ opac/webapp/admin/forms.py | 2 +- opac/webapp/admin/views.py | 44 ++++++++++++++----------- opac/webapp/choices.py | 4 +-- opac/webapp/controllers.py | 6 ++-- opac/webapp/forms.py | 2 +- opac/webapp/main/views.py | 6 ++-- 8 files changed, 46 insertions(+), 42 deletions(-) diff --git a/opac/tests/test_admin_custom_filters.py b/opac/tests/test_admin_custom_filters.py index e1453dc2e..b6af75c94 100644 --- a/opac/tests/test_admin_custom_filters.py +++ b/opac/tests/test_admin_custom_filters.py @@ -2,8 +2,8 @@ import unittest from uuid import uuid4 -from flask_admin.contrib.mongoengine.tools import parse_like_term -from flask_babelex import lazy_gettext as __ +from flask_admin.contrib.pymongo.tools import parse_like_term +from flask_babel import lazy_gettext as __ from mongoengine.queryset import Q from opac_schema.v1.models import Article, Issue, Journal from tests.utils import makeOneArticle, makeOneIssue, makeOneJournal diff --git a/opac/webapp/__init__.py b/opac/webapp/__init__.py index e25bd0505..01d69483b 100644 --- a/opac/webapp/__init__.py +++ b/opac/webapp/__init__.py @@ -4,15 +4,15 @@ import flask_admin import rq_dashboard -import rq_scheduler_dashboard +# import rq_scheduler_dashboard from elasticapm.contrib.flask import ElasticAPM from flask import Flask, flash, redirect, request, url_for -from flask_babelex import Babel, lazy_gettext +from flask_babel import Babel, lazy_gettext from flask_caching import Cache from flask_htmlmin import HTMLMIN from flask_login import LoginManager, current_user from flask_mail import Mail -from flask_mongoengine import MongoEngine +from flask_mongoengine2 import MongoEngine from flask_sqlalchemy import SQLAlchemy from opac_schema.v1.models import ( Article, @@ -28,6 +28,7 @@ from raven.contrib.flask import Sentry from werkzeug.middleware.proxy_fix import ProxyFix from werkzeug.routing import BaseConverter +# from webapp.main.views import get_locale login_manager = LoginManager() dbmongo = MongoEngine() @@ -125,7 +126,7 @@ def create_app(): # Configurações app.config.from_object(rq_dashboard.default_settings) - app.config.from_object(rq_scheduler_dashboard.default_settings) + # app.config.from_object(rq_scheduler_dashboard.default_settings) app.config.from_object("webapp.config.default") # Configuração basica app.config.from_envvar("OPAC_CONFIG", silent=True) # configuração do ambiente app.logger.root.setLevel(app.config.get("LOG_LEVEL")) @@ -150,9 +151,9 @@ def create_app(): # Registrando os filtros app.jinja_env.filters["trans_alpha2"] = custom_filters.trans_alpha2 app.jinja_env.filters["datetimefilter"] = custom_filters.datetimefilter - + from webapp.main.views import get_locale # i18n - babel.init_app(app) + babel.init_app(app, locale_selector=get_locale) # Debug Toolbar if app.config["DEBUG"]: # Toolbar @@ -183,7 +184,6 @@ def create_app(): app, "OPAC admin", index_view=views.AdminIndexView(), - template_mode="bootstrap3", base_template="admin/opac_base.html", ) @@ -261,9 +261,9 @@ def check_user_logged_in_or_redirect(): # Use `with app.app_context()` within the `create_app` definition. with app.app_context(): - app.register_blueprint( - rq_scheduler_dashboard.blueprint, url_prefix="/admin/scheduler" - ) + # app.register_blueprint( + # rq_scheduler_dashboard.blueprint, url_prefix="/admin/scheduler" + # ) app.register_blueprint(rq_dashboard.blueprint, url_prefix="/admin/workers") # FIM do setup RQ Dashboard e Scheduler: - mover para um modulo proprio diff --git a/opac/webapp/admin/forms.py b/opac/webapp/admin/forms.py index 39ecad971..2bdb44642 100644 --- a/opac/webapp/admin/forms.py +++ b/opac/webapp/admin/forms.py @@ -1,6 +1,6 @@ # coding: utf-8 -from flask_babelex import gettext as _ +from flask_babel import gettext as _ from webapp import controllers from wtforms import fields, form, validators diff --git a/opac/webapp/admin/views.py b/opac/webapp/admin/views.py index ffea82321..3f65fc68e 100644 --- a/opac/webapp/admin/views.py +++ b/opac/webapp/admin/views.py @@ -17,13 +17,13 @@ url_for, ) from flask_admin.actions import action -from flask_admin.contrib import mongoengine, sqla -from flask_admin.contrib.mongoengine.tools import parse_like_term +from flask_admin.contrib import pymongo, sqla +from flask_admin.contrib.pymongo.tools import parse_like_term from flask_admin.form import Select2Field from flask_admin.model.form import InlineFormAdmin -from flask_babelex import gettext as _ -from flask_babelex import lazy_gettext as __ -from jinja2 import Markup +from flask_babel import gettext as _ +from flask_babel import lazy_gettext as __ +from markupsafe import Markup from legendarium.formatter import descriptive_short_format from mongoengine import ( EmailField, @@ -38,7 +38,7 @@ from webapp.admin import custom_fields, forms from webapp.admin.ajax import CustomQueryAjaxModelLoader from webapp.admin.custom_filters import ( - CustomFilterConverter, + # CustomFilterConverter, CustomFilterConverterSqla, get_flt, ) @@ -375,7 +375,7 @@ def search_placeholder(self): ) -class OpacBaseAdminView(mongoengine.ModelView): +class OpacBaseAdminView(pymongo.ModelView): page_size = 20 can_create = False can_edit = False @@ -390,7 +390,7 @@ class OpacBaseAdminView(mongoengine.ModelView): EmbeddedDocumentField, ReferenceField, ) - filter_converter = CustomFilterConverter() + # filter_converter = CustomFilterConverter() object_id_converter = str def _search(self, query, search_term): @@ -1155,17 +1155,23 @@ class PressReleaseAdminView(OpacBaseAdminView): form_overrides = dict(language=Select2Field, content=CKEditorField) form_ajax_refs = { - "journal": CustomQueryAjaxModelLoader( - name="journal", - model=Journal, - fields=["title", "acronym", "scielo_issn", "print_issn", "eletronic_issn"], - ), - "issue": CustomQueryAjaxModelLoader( - name="issue", model=Issue, fields=["label", "pid", "journal"] - ), - "article": CustomQueryAjaxModelLoader( - name="article", model=Article, fields=["title", "doi", "pid"] - ), + "journal": { + "fields": ("title", "acronym", "scielo_issn", "print_issn", "eletronic_issn"), + "placeholder": "Please Select", + "page_size": 10, + "minimun_input_length": 0, + }, + # "journal": CustomQueryAjaxModelLoader( + # name="journal", + # model=Journal, + # fields=["title", "acronym", "scielo_issn", "print_issn", "eletronic_issn"], + # ), + # "issue": CustomQueryAjaxModelLoader( + # name="issue", model=Issue, fields=["label", "pid", "journal"] + # ), + # "article": CustomQueryAjaxModelLoader( + # name="article", model=Article, fields=["title", "doi", "pid"] + # ), } form_args = dict( diff --git a/opac/webapp/choices.py b/opac/webapp/choices.py index 7b2dbd347..d36d205d5 100644 --- a/opac/webapp/choices.py +++ b/opac/webapp/choices.py @@ -1,7 +1,7 @@ # coding: utf-8 -from flask_babelex import gettext as _ -from flask_babelex import lazy_gettext as __ +from flask_babel import gettext as _ +from flask_babel import lazy_gettext as __ UNPUBLISH_REASONS = [ _("Conteúdo temporariamente indisponível"), diff --git a/opac/webapp/controllers.py b/opac/webapp/controllers.py index c91caf558..ed601b827 100644 --- a/opac/webapp/controllers.py +++ b/opac/webapp/controllers.py @@ -19,9 +19,9 @@ import unicodecsv import xlsxwriter from flask import current_app, url_for -from flask_babelex import gettext as _ -from flask_babelex import lazy_gettext as __ -from flask_mongoengine import Pagination +from flask_babel import gettext as _ +from flask_babel import lazy_gettext as __ +from flask_mongoengine2 import Pagination from legendarium.formatter import descriptive_very_short_format from mongoengine import Q from mongoengine.errors import InvalidQueryError diff --git a/opac/webapp/forms.py b/opac/webapp/forms.py index c2895655b..3f2090026 100644 --- a/opac/webapp/forms.py +++ b/opac/webapp/forms.py @@ -2,7 +2,7 @@ import re -from flask_babelex import gettext as _ +from flask_babel import gettext as _ from flask_wtf import FlaskForm from wtforms import HiddenField, StringField, TextAreaField from wtforms.validators import URL, DataRequired, Email, ValidationError diff --git a/opac/webapp/main/views.py b/opac/webapp/main/views.py index 2c420f611..acd4f7052 100644 --- a/opac/webapp/main/views.py +++ b/opac/webapp/main/views.py @@ -25,18 +25,17 @@ session, url_for, ) -from flask_babelex import gettext as _ +from flask_babel import gettext as _ from legendarium.formatter import descriptive_short_format from lxml import etree from opac_schema.v1.models import Article, Collection, Issue, Journal from packtools import HTMLGenerator -from webapp import babel, cache, controllers, forms +from webapp import cache, controllers, forms from webapp.choices import STUDY_AREAS from webapp.controllers import create_press_release_record from webapp.config.lang_names import display_original_lang_name from webapp.utils import utils from webapp.utils.caching import cache_key_with_lang, cache_key_with_lang_with_qs -from webapp.main.errors import page_not_found, internal_server_error from . import helper @@ -110,7 +109,6 @@ def add_scielo_org_config_to_g(): setattr(g, "scielo_org", scielo_org_links) -@babel.localeselector def get_locale(): langs = current_app.config.get("LANGUAGES") lang_from_headers = request.accept_languages.best_match(list(langs.keys())) From a925e66abf748646aa467cbd492bf49c084f372b Mon Sep 17 00:00:00 2001 From: Samuel Veiga Rangel Date: Fri, 15 Nov 2024 12:13:10 -0300 Subject: [PATCH 3/3] Novos filters --- opac/webapp/admin/ajax.py | 7 +- opac/webapp/admin/custom_filters.py | 102 ++++++++++++++++------------ 2 files changed, 62 insertions(+), 47 deletions(-) diff --git a/opac/webapp/admin/ajax.py b/opac/webapp/admin/ajax.py index f8a89b4f9..59dd125ae 100644 --- a/opac/webapp/admin/ajax.py +++ b/opac/webapp/admin/ajax.py @@ -1,16 +1,19 @@ # coding: utf-8 from flask_admin._compat import as_unicode -from flask_admin.contrib.mongoengine.ajax import QueryAjaxModelLoader +from flask_admin.contrib.sqla.ajax import QueryAjaxModelLoader +from flask_admin.model.ajax import AjaxModelLoader -class CustomQueryAjaxModelLoader(QueryAjaxModelLoader): +class CustomQueryAjaxModelLoader(AjaxModelLoader): def __init__(self, name, model, **options): """ Constructor. :param fields: Fields to run query against """ + super(CustomQueryAjaxModelLoader, self).__init__(name, model, **options) + self.model = model def format(self, model): # mudança minima porém necessária, o atributo id no modelo é _id diff --git a/opac/webapp/admin/custom_filters.py b/opac/webapp/admin/custom_filters.py index 904681703..ee722cd4f 100644 --- a/opac/webapp/admin/custom_filters.py +++ b/opac/webapp/admin/custom_filters.py @@ -1,22 +1,20 @@ # coding: utf-8 from flask_admin.contrib import sqla -from flask_admin.contrib.mongoengine.filters import ( - FilterConverter, - FilterEmpty, +from flask_admin.contrib.pymongo.filters import ( + BasePyMongoFilter, FilterEqual, - FilterInList, FilterLike, FilterNotEqual, - FilterNotInList, FilterNotLike, ) -from flask_admin.contrib.mongoengine.tools import parse_like_term +from flask_admin.contrib.pymongo.tools import parse_like_term from flask_admin.model import filters from mongoengine import EmbeddedDocumentField, ListField, ReferenceField, StringField from mongoengine.queryset import Q from opac_schema.v1.models import Issue, Journal from webapp import models +from flask_admin.babel import lazy_gettext def get_flt(column=None, value=None, term=""): @@ -102,61 +100,75 @@ def apply(self, query, value): return query.filter(flt) -class CustomFilterEmpty(FilterEmpty): +class CustomFilterEmpty(BasePyMongoFilter): def apply(self, query, value): if value == "1": flt = get_flt(self.column, None) else: flt = get_flt(self.column, None, "ne") return query.filter(flt) + + def operation(self): + return lazy_gettext('empty') -class CustomFilterInList(FilterInList): +class CustomFilterInList(BasePyMongoFilter): + def __init__(self, column, name, options=None, data_type=None): + super(CustomFilterInList, self).__init__(column, name, options, data_type='select2-tags') + def apply(self, query, value): flt = get_flt(self.column, value, "in") return query.filter(flt) + def clean(self, value): + return [v.strip() for v in value.split(',') if v.strip()] + def operation(self): + return lazy_gettext('in list') -class CustomFilterNotInList(FilterNotInList): +class CustomFilterNotInList(BasePyMongoFilter): def apply(self, query, value): flt = get_flt(self.column, value, "nin") return query.filter(flt) - - -class CustomFilterConverter(FilterConverter): - # Campos dentro filtros ReferenceField, EmbeddedDocumentField, ListField - # deve ser do tipo StringField - - reference_filters = ( - CustomFilterLike, - CustomFilterNotLike, - CustomFilterEqual, - CustomFilterNotEqual, - CustomFilterInList, - CustomFilterNotInList, - ) - embedded_filters = ( - CustomFilterLike, - CustomFilterNotLike, - CustomFilterEqual, - CustomFilterNotEqual, - CustomFilterEmpty, - CustomFilterInList, - CustomFilterNotInList, - ) - list_filters = (CustomFilterLike, CustomFilterNotLike, CustomFilterEmpty) - - @filters.convert("ReferenceField") - def conv_reference(self, column, name): - return [f(column, name) for f in self.reference_filters] - - @filters.convert("EmbeddedDocumentField") - def conv_embedded(self, column, name): - return [f(column, name) for f in self.embedded_filters] - - @filters.convert("ListField") - def conv_list(self, column, name): - return [f(column, name) for f in self.list_filters] + + def operation(self): + return lazy_gettext('not in list') + + +# FIXME +# class CustomFilterConverter(FilterConverter): +# # Campos dentro filtros ReferenceField, EmbeddedDocumentField, ListField +# # deve ser do tipo StringField + +# reference_filters = ( +# CustomFilterLike, +# CustomFilterNotLike, +# CustomFilterEqual, +# CustomFilterNotEqual, +# CustomFilterInList, +# CustomFilterNotInList, +# ) +# embedded_filters = ( +# CustomFilterLike, +# CustomFilterNotLike, +# CustomFilterEqual, +# CustomFilterNotEqual, +# CustomFilterEmpty, +# CustomFilterInList, +# CustomFilterNotInList, +# ) +# list_filters = (CustomFilterLike, CustomFilterNotLike, CustomFilterEmpty) + +# @filters.convert("ReferenceField") +# def conv_reference(self, column, name): +# return [f(column, name) for f in self.reference_filters] + +# @filters.convert("EmbeddedDocumentField") +# def conv_embedded(self, column, name): +# return [f(column, name) for f in self.embedded_filters] + +# @filters.convert("ListField") +# def conv_list(self, column, name): +# return [f(column, name) for f in self.list_filters] class CustomFilterConverterSqla(sqla.filters.FilterConverter):