Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[SDESK-7387] Update quart_babel to 1.0.7 #1153

Merged
merged 4 commits into from
Nov 10, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
25 changes: 6 additions & 19 deletions dev-requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,6 @@ arrow==1.3.0
# via
# eve-elastic
# superdesk-core
asgi-tools==1.0.10
# via quart-babel
asgiref==3.8.1
# via superdesk-core
asn1crypto==1.5.1
Expand All @@ -36,7 +34,6 @@ asn1crypto==1.5.1
async-timeout==4.0.3
# via
# aiohttp
# asgi-tools
# redis
attrs==24.2.0
# via aiohttp
Expand All @@ -61,9 +58,9 @@ blinker==1.8.2
# raven
# sentry-sdk
# superdesk-core
boto3==1.35.52
boto3==1.35.55
# via superdesk-core
botocore==1.35.52
botocore==1.35.55
# via
# boto3
# s3transfer
Expand Down Expand Up @@ -198,8 +195,6 @@ html5lib==1.1
# via xhtml2pdf
httmock==1.4.0
# via -r dev-requirements.in
http-router==4.1.2
# via asgi-tools
httplib2==0.22.0
# via oauth2client
hypercorn==0.17.3
Expand All @@ -215,8 +210,6 @@ idna==3.10
# email-validator
# requests
# yarl
importlib-metadata==8.5.0
# via quart-babel
iniconfig==2.0.0
# via pytest
isodate==0.7.2
Expand Down Expand Up @@ -268,7 +261,6 @@ motor==3.5.3
multidict==6.1.0
# via
# aiohttp
# asgi-tools
# yarl
mypy==1.13.0
# via -r mypy-requirements.txt
Expand Down Expand Up @@ -410,7 +402,7 @@ quart @ git+https://github.com/MarkLark86/quart@fix-test-client-with-utf8-url
# quart-wtforms
# sentry-sdk
# superdesk-core
quart-babel @ git+https://github.com/MarkLark86/quart-babel@fix-get-format
quart-babel==1.0.7
# via superdesk-core
quart-flask-patch==0.3.0
# via superdesk-core
Expand Down Expand Up @@ -468,8 +460,6 @@ six==1.16.0
# parse-type
# python-bidi
# python-dateutil
sniffio==1.3.1
# via asgi-tools
superdesk-core @ git+https://github.com/superdesk/superdesk-core.git@async
# via -r requirements.txt
superdesk-planning @ git+https://github.com/superdesk/superdesk-planning.git@async
Expand Down Expand Up @@ -510,6 +500,7 @@ types-python-dateutil==2.9.0.20241003
types-pytz==2024.2.0.20241003
# via
# -r mypy-requirements.txt
# quart-babel
# types-tzlocal
types-requests==2.31.0.6
# via -r mypy-requirements.txt
Expand Down Expand Up @@ -569,7 +560,7 @@ webencodings==0.5.1
# tinycss2
websockets==13.0.1
# via superdesk-core
werkzeug==3.0.6
werkzeug==3.1.2
# via
# flask
# quart
Expand All @@ -591,11 +582,7 @@ xmlsec==1.3.14
# python3-saml
# superdesk-core
yarl==1.17.1
# via
# aiohttp
# asgi-tools
zipp==3.20.2
# via importlib-metadata
# via aiohttp

# The following packages are considered to be unsafe in a requirements file:
# setuptools
8 changes: 4 additions & 4 deletions newsroom/agenda/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -93,11 +93,11 @@ def get_coverage_scheduled(coverage):
return coverage.get("scheduled") or (coverage.get("planning") or {}).get("scheduled")


async def get_coverage_content_type_name(coverage, language):
def get_coverage_content_type_name(coverage, language):
coverage_types = get_app_config("COVERAGE_TYPES")
content_type = coverage.get("coverage_type") or coverage.get("planning", {}).get("g2_content_type", "")
coverage_type = coverage_types.get(content_type, {})
locale = (language or await get_session_locale() or "en").lower()
locale = (language or get_session_locale() or "en").lower()

return coverage_type.get("translations", {}).get(locale) or coverage_type.get("name")

Expand Down Expand Up @@ -134,8 +134,8 @@ def get_coverage_status_text(coverage):
)


async def get_coverage_email_text(coverage, default_state="", language=None):
content_type = await get_coverage_content_type_name(coverage, language)
def get_coverage_email_text(coverage, default_state="", language=None):
content_type = get_coverage_content_type_name(coverage, language)
status = default_state or get_coverage_status_text(coverage)
slugline = coverage.get("slugline") or coverage.get("planning", {}).get("slugline", "")

Expand Down
13 changes: 4 additions & 9 deletions newsroom/factory/app.py
Original file line number Diff line number Diff line change
Expand Up @@ -145,18 +145,13 @@ def setup_media_storage(self):
self.media = SuperdeskGridFSMediaStorage(self)

def setup_babel(self):
# TODO-ASYNC: Add support to quart_babel to support multiple directories on the domain
# Set `root_path` to `NEWSROOM_DIR`, so quart-babel imports translations from newsroom.translations
self.root_path = str(NEWSROOM_DIR)
self.config.setdefault("BABEL_TRANSLATION_DIRECTORIES", os.path.join(NEWSROOM_DIR, "translations"))

if self.config.get("TRANSLATIONS_PATH"):
self.config["BABEL_TRANSLATION_DIRECTORIES"] = ";".join(
[
str(self.config["BABEL_TRANSLATION_DIRECTORIES"]),
str(self.config["TRANSLATIONS_PATH"]),
]
)
self.config["BABEL_TRANSLATION_DIRECTORIES"] = [
str(self.config["BABEL_TRANSLATION_DIRECTORIES"]),
str(self.config["TRANSLATIONS_PATH"]),
]

# avoid events on this
self.babel_tzinfo = None
Expand Down
10 changes: 5 additions & 5 deletions newsroom/gettext.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
from babel import core
from quart_babel import Babel, format_datetime, get_domain
from quart_babel.typing import ASGIRequest
from quart_babel import Babel, format_datetime
from quart_babel.domain import get_domain

from superdesk.core import get_app_config, get_current_app
from superdesk.flask import request, session
Expand All @@ -9,7 +9,7 @@


def get_client_translations(domain="client"):
translations = get_domain().translations
translations = get_domain().get_translations()
return {key: val for key, val in translations._catalog.items() if key and val}


Expand All @@ -27,7 +27,7 @@ def get_client_locales():
return client_locales


async def get_session_locale(_req: ASGIRequest | None = None):
def get_session_locale():
from newsroom.auth.utils import get_user_or_none_from_request

try:
Expand Down Expand Up @@ -61,7 +61,7 @@ def get_user_timezone(user: User) -> str:
return get_app_config("BABEL_DEFAULT_TIMEZONE") or get_app_config("DEFAULT_TIMEZONE")


async def get_session_timezone(_req: ASGIRequest | None = None):
def get_session_timezone():
from newsroom.auth.utils import get_user_or_none_from_request

try:
Expand Down
2 changes: 1 addition & 1 deletion newsroom/notifications/commands.py
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ async def run_schedules(self, force: bool):
if not user.get("notification_schedule"):
user["notification_schedule"] = {}

user["notification_schedule"].setdefault("timezone", await get_session_timezone())
user["notification_schedule"].setdefault("timezone", get_session_timezone())
user["notification_schedule"].setdefault(
"times", get_app_config("DEFAULT_SCHEDULED_NOTIFICATION_TIMES")
)
Expand Down
2 changes: 1 addition & 1 deletion newsroom/public/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ def init_module(app: SuperdeskAsyncApp):


async def render_restricted_action_modal_body():
locale = (await get_session_locale() or "en").lower()
locale = (get_session_locale() or "en").lower()
template_name = get_language_template_name("public_restricted_action_modal_body", locale, "html")

return await render_template(template_name)
2 changes: 1 addition & 1 deletion newsroom/search/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ def init_app(app):


async def render_search_tips_html(search_type) -> str:
locale = (await get_session_locale() or "en").lower()
locale = (get_session_locale() or "en").lower()
template_name = get_language_template_name(f"search_tips_{search_type}", locale, "html")

return await render_template(template_name)
4 changes: 2 additions & 2 deletions newsroom/template_filters.py
Original file line number Diff line number Diff line change
Expand Up @@ -117,13 +117,13 @@ def is_item_tbc(item: dict) -> bool:
return event_tbc or (planning and planning[0].get("_time_to_be_confirmed", False))


async def format_event_datetime(item: dict) -> str:
def format_event_datetime(item: dict) -> str:
date_info = item.get("dates", {})

if not date_info:
return ""

tz = date_info.get("tz", await get_session_timezone())
tz = date_info.get("tz", get_session_timezone())
# Set the session timezone
with template_locale(timezone=tz):
start = parse_date(date_info.get("start"))
Expand Down
34 changes: 22 additions & 12 deletions newsroom/template_loaders.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
from contextlib import contextmanager

import pytz
import jinja2

from typing import Optional
from quart_babel import get_locale, switch_locale, switch_timezone
from quart_babel import get_timezone, force_locale
from quart_babel.utils import _get_current_context

from superdesk.flask import g

Expand All @@ -29,19 +31,27 @@ def noop():
def template_locale(locale: Optional[str] = None, timezone: Optional[str] = None):
"""Overriding babel locale and timezone using internals, but there is no public api for that."""

if locale and timezone:
with switch_locale(locale), switch_timezone(timezone):
set_template_locale(str(get_locale()))
yield
set_template_locale(None)
elif locale:
with switch_locale(locale):
set_template_locale(str(get_locale()))
ctx = _get_current_context()

if ctx is None or (locale is None and timezone is None):
yield
return

old_tzinfo = get_timezone()

try:
if timezone:
ctx.babel_tzinfo = pytz.timezone(timezone)
if locale:
set_template_locale(locale)
with force_locale(locale):
yield
else:
yield
finally:
if timezone:
ctx.babel_tzinfo = old_tzinfo
set_template_locale(None)
elif timezone:
with switch_timezone(timezone):
yield


class LocaleTemplateLoader(jinja2.FileSystemLoader):
Expand Down
2 changes: 1 addition & 1 deletion newsroom/wire/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -551,7 +551,7 @@ async def copy(args: WireItemRouteArgs, params: ItemActionUrlParams, request: Re
await request.abort(404)

template_filename = "copy_agenda_item" if item_type == "agenda" else "copy_wire_item"
locale = (await get_session_locale() or "en").lower()
locale = (get_session_locale() or "en").lower()
template_name = get_language_template_name(template_filename, locale, "txt")

template_kwargs = {"item": item}
Expand Down
2 changes: 1 addition & 1 deletion tests/core/test_gettext.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,4 @@

async def test_get_session_locale(app):
async with app.app_context():
assert "en" == await get_session_locale()
assert "en" == get_session_locale()
19 changes: 9 additions & 10 deletions tests/core/test_template_filters.py
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ async def test_format_event_datetime():
"no_end_time": False,
},
}
assert "Date: 01/11/2023 00:00 to 02/11/2023 02:15 (Asia/Calcutta)" == await format_event_datetime(event1)
assert "Date: 01/11/2023 00:00 to 02/11/2023 02:15 (Asia/Calcutta)" == format_event_datetime(event1)

# Case 2: All-day event
event2 = {
Expand All @@ -77,7 +77,7 @@ async def test_format_event_datetime():
"no_end_time": False,
},
}
assert "Date: 18/12/2023 00:00 (Asia/Calcutta)" == await format_event_datetime(event2)
assert "Date: 18/12/2023 00:00 (Asia/Calcutta)" == format_event_datetime(event2)

# Case 3: Time-to-be-confirmed event
event3 = {
Expand All @@ -92,9 +92,8 @@ async def test_format_event_datetime():
"_time_to_be_confirmed": True,
},
}
assert (
"Date: 01/11/2023 00:00 to 02/11/2023 02:15 (Asia/Calcutta) (Time to be confirmed)"
== await format_event_datetime(event3)
assert "Date: 01/11/2023 00:00 to 02/11/2023 02:15 (Asia/Calcutta) (Time to be confirmed)" == format_event_datetime(
event3
)

# Case 4: Event with no end time
Expand All @@ -106,7 +105,7 @@ async def test_format_event_datetime():
"no_end_time": True,
}
}
assert "Date: 01/11/2023 00:00 (Asia/Calcutta)" == await format_event_datetime(event4)
assert "Date: 01/11/2023 00:00 (Asia/Calcutta)" == format_event_datetime(event4)

# Case 5: All-day event with no_end_time
event5 = {
Expand All @@ -118,7 +117,7 @@ async def test_format_event_datetime():
"no_end_time": True,
},
}
assert "Date: 01/11/2023 00:00 (Asia/Calcutta)" == await format_event_datetime(event5)
assert "Date: 01/11/2023 00:00 (Asia/Calcutta)" == format_event_datetime(event5)

# Case 6: Multi-day event
event6 = {
Expand All @@ -130,7 +129,7 @@ async def test_format_event_datetime():
"no_end_time": False,
},
}
assert "Date: 01/11/2023 00:00 to 03/11/2023 02:15 (Asia/Calcutta)" == await format_event_datetime(event6)
assert "Date: 01/11/2023 00:00 to 03/11/2023 02:15 (Asia/Calcutta)" == format_event_datetime(event6)

# Case 7: REGULAR schedule_type with end_time
event7 = {
Expand All @@ -142,7 +141,7 @@ async def test_format_event_datetime():
"no_end_time": False,
}
}
assert "Time: 00:59 AM to 21:00 PM on Date: November 2, 2023 (Asia/Calcutta)" == await format_event_datetime(event7)
assert "Time: 00:59 AM to 21:00 PM on Date: November 2, 2023 (Asia/Calcutta)" == format_event_datetime(event7)

# Case 8: REGULAR schedule_type with no end time
event8 = {
Expand All @@ -153,4 +152,4 @@ async def test_format_event_datetime():
"no_end_time": True,
},
}
assert "Date: 02/11/2023 00:00 (Asia/Calcutta)" == await format_event_datetime(event8)
assert "Date: 02/11/2023 00:00 (Asia/Calcutta)" == format_event_datetime(event8)
Loading