mirror of
https://gitlab.archlinux.org/archlinux/aurweb.git
synced 2025-02-03 10:43:03 +01:00
housekeep: define filters in their own modules
This patch cleans up aurweb.templates and removes direct module-level initialization of the environment. Signed-off-by: Kevin Morris <kevr@0cost.org>
This commit is contained in:
parent
fca175ed84
commit
211ca5e49c
16 changed files with 159 additions and 159 deletions
|
@ -19,7 +19,9 @@ from starlette.exceptions import HTTPException as StarletteHTTPException
|
||||||
from starlette.middleware.authentication import AuthenticationMiddleware
|
from starlette.middleware.authentication import AuthenticationMiddleware
|
||||||
from starlette.middleware.sessions import SessionMiddleware
|
from starlette.middleware.sessions import SessionMiddleware
|
||||||
|
|
||||||
|
import aurweb.captcha # noqa: F401
|
||||||
import aurweb.config
|
import aurweb.config
|
||||||
|
import aurweb.filters # noqa: F401
|
||||||
import aurweb.logging
|
import aurweb.logging
|
||||||
import aurweb.pkgbase.util as pkgbaseutil
|
import aurweb.pkgbase.util as pkgbaseutil
|
||||||
|
|
||||||
|
|
|
@ -13,7 +13,7 @@ from starlette.requests import HTTPConnection
|
||||||
|
|
||||||
import aurweb.config
|
import aurweb.config
|
||||||
|
|
||||||
from aurweb import db, l10n, util
|
from aurweb import db, filters, l10n, util
|
||||||
from aurweb.models import Session, User
|
from aurweb.models import Session, User
|
||||||
from aurweb.models.account_type import ACCOUNT_TYPE_ID
|
from aurweb.models.account_type import ACCOUNT_TYPE_ID
|
||||||
|
|
||||||
|
@ -166,7 +166,7 @@ def _auth_required(auth_goal: bool = True):
|
||||||
raise HTTPException(status_code=HTTPStatus.BAD_REQUEST,
|
raise HTTPException(status_code=HTTPStatus.BAD_REQUEST,
|
||||||
detail=_("Bad Referer header."))
|
detail=_("Bad Referer header."))
|
||||||
url = referer[len(aur) - 1:]
|
url = referer[len(aur) - 1:]
|
||||||
url = "/login?" + util.urlencode({"next": url})
|
url = "/login?" + filters.urlencode({"next": url})
|
||||||
return RedirectResponse(url, status_code=int(HTTPStatus.SEE_OTHER))
|
return RedirectResponse(url, status_code=int(HTTPStatus.SEE_OTHER))
|
||||||
return wrapper
|
return wrapper
|
||||||
|
|
||||||
|
|
|
@ -5,6 +5,7 @@ from jinja2 import pass_context
|
||||||
|
|
||||||
from aurweb.db import query
|
from aurweb.db import query
|
||||||
from aurweb.models import User
|
from aurweb.models import User
|
||||||
|
from aurweb.templates import register_filter
|
||||||
|
|
||||||
|
|
||||||
def get_captcha_salts():
|
def get_captcha_salts():
|
||||||
|
@ -41,6 +42,7 @@ def get_captcha_answer(token):
|
||||||
return hashlib.md5((text + "\n").encode()).hexdigest()[:6]
|
return hashlib.md5((text + "\n").encode()).hexdigest()[:6]
|
||||||
|
|
||||||
|
|
||||||
|
@register_filter("captcha_salt")
|
||||||
@pass_context
|
@pass_context
|
||||||
def captcha_salt_filter(context):
|
def captcha_salt_filter(context):
|
||||||
""" Returns the most recent CAPTCHA salt in the list of salts. """
|
""" Returns the most recent CAPTCHA salt in the list of salts. """
|
||||||
|
@ -48,6 +50,7 @@ def captcha_salt_filter(context):
|
||||||
return salts[0]
|
return salts[0]
|
||||||
|
|
||||||
|
|
||||||
|
@register_filter("captcha_cmdline")
|
||||||
@pass_context
|
@pass_context
|
||||||
def captcha_cmdline_filter(context, salt):
|
def captcha_cmdline_filter(context, salt):
|
||||||
""" Returns a CAPTCHA challenge for a given salt. """
|
""" Returns a CAPTCHA challenge for a given salt. """
|
||||||
|
|
|
@ -1,10 +1,19 @@
|
||||||
from typing import Any, Dict
|
import copy
|
||||||
|
import math
|
||||||
|
|
||||||
|
from datetime import datetime
|
||||||
|
from typing import Any, Dict
|
||||||
|
from urllib.parse import quote_plus, urlencode
|
||||||
|
from zoneinfo import ZoneInfo
|
||||||
|
|
||||||
|
import fastapi
|
||||||
import paginate
|
import paginate
|
||||||
|
|
||||||
from jinja2 import pass_context
|
from jinja2 import pass_context
|
||||||
|
|
||||||
from aurweb import config, util
|
import aurweb.models
|
||||||
|
|
||||||
|
from aurweb import config, l10n
|
||||||
from aurweb.templates import register_filter, register_function
|
from aurweb.templates import register_filter, register_function
|
||||||
|
|
||||||
|
|
||||||
|
@ -30,7 +39,7 @@ def pager_nav(context: Dict[str, Any],
|
||||||
def create_url(page: int):
|
def create_url(page: int):
|
||||||
nonlocal q
|
nonlocal q
|
||||||
offset = max(page * pp - pp, 0)
|
offset = max(page * pp - pp, 0)
|
||||||
qs = util.to_qs(util.extend_query(q, ["O", offset]))
|
qs = to_qs(extend_query(q, ["O", offset]))
|
||||||
return f"{prefix}?{qs}"
|
return f"{prefix}?{qs}"
|
||||||
|
|
||||||
# Use the paginate module to produce our linkage.
|
# Use the paginate module to produce our linkage.
|
||||||
|
@ -58,3 +67,84 @@ def config_getint(section: str, key: str) -> int:
|
||||||
@register_function("round")
|
@register_function("round")
|
||||||
def do_round(f: float) -> int:
|
def do_round(f: float) -> int:
|
||||||
return round(f)
|
return round(f)
|
||||||
|
|
||||||
|
|
||||||
|
@register_filter("tr")
|
||||||
|
@pass_context
|
||||||
|
def tr(context: Dict[str, Any], value: str):
|
||||||
|
""" A translation filter; example: {{ "Hello" | tr("de") }}. """
|
||||||
|
_ = l10n.get_translator_for_request(context.get("request"))
|
||||||
|
return _(value)
|
||||||
|
|
||||||
|
|
||||||
|
@register_filter("tn")
|
||||||
|
@pass_context
|
||||||
|
def tn(context: Dict[str, Any], count: int,
|
||||||
|
singular: str, plural: str) -> str:
|
||||||
|
""" A singular and plural translation filter.
|
||||||
|
|
||||||
|
Example:
|
||||||
|
{{ some_integer | tn("singular %d", "plural %d") }}
|
||||||
|
|
||||||
|
:param context: Response context
|
||||||
|
:param count: The number used to decide singular or plural state
|
||||||
|
:param singular: The singular translation
|
||||||
|
:param plural: The plural translation
|
||||||
|
:return: Translated string
|
||||||
|
"""
|
||||||
|
gettext = l10n.get_raw_translator_for_request(context.get("request"))
|
||||||
|
return gettext.ngettext(singular, plural, count)
|
||||||
|
|
||||||
|
|
||||||
|
@register_filter("dt")
|
||||||
|
def timestamp_to_datetime(timestamp: int):
|
||||||
|
return datetime.utcfromtimestamp(int(timestamp))
|
||||||
|
|
||||||
|
|
||||||
|
@register_filter("as_timezone")
|
||||||
|
def as_timezone(dt: datetime, timezone: str):
|
||||||
|
return dt.astimezone(tz=ZoneInfo(timezone))
|
||||||
|
|
||||||
|
|
||||||
|
@register_filter("extend_query")
|
||||||
|
def extend_query(query: Dict[str, Any], *additions) -> Dict[str, Any]:
|
||||||
|
""" Add additional key value pairs to query. """
|
||||||
|
q = copy.copy(query)
|
||||||
|
for k, v in list(additions):
|
||||||
|
q[k] = v
|
||||||
|
return q
|
||||||
|
|
||||||
|
|
||||||
|
@register_filter("urlencode")
|
||||||
|
def to_qs(query: Dict[str, Any]) -> str:
|
||||||
|
return urlencode(query, doseq=True)
|
||||||
|
|
||||||
|
|
||||||
|
@register_filter("get_vote")
|
||||||
|
def get_vote(voteinfo, request: fastapi.Request):
|
||||||
|
from aurweb.models import TUVote
|
||||||
|
return voteinfo.tu_votes.filter(TUVote.User == request.user).first()
|
||||||
|
|
||||||
|
|
||||||
|
@register_filter("number_format")
|
||||||
|
def number_format(value: float, places: int):
|
||||||
|
""" A converter function similar to PHP's number_format. """
|
||||||
|
return f"{value:.{places}f}"
|
||||||
|
|
||||||
|
|
||||||
|
@register_filter("account_url")
|
||||||
|
@pass_context
|
||||||
|
def account_url(context: Dict[str, Any],
|
||||||
|
user: "aurweb.models.user.User") -> str:
|
||||||
|
base = aurweb.config.get("options", "aur_location")
|
||||||
|
return f"{base}/account/{user.Username}"
|
||||||
|
|
||||||
|
|
||||||
|
@register_filter("quote_plus")
|
||||||
|
def _quote_plus(*args, **kwargs) -> str:
|
||||||
|
return quote_plus(*args, **kwargs)
|
||||||
|
|
||||||
|
|
||||||
|
@register_filter("ceil")
|
||||||
|
def ceil(*args, **kwargs) -> int:
|
||||||
|
return math.ceil(*args, **kwargs)
|
||||||
|
|
|
@ -1,10 +1,8 @@
|
||||||
import gettext
|
import gettext
|
||||||
import typing
|
|
||||||
|
|
||||||
from collections import OrderedDict
|
from collections import OrderedDict
|
||||||
|
|
||||||
from fastapi import Request
|
from fastapi import Request
|
||||||
from jinja2 import pass_context
|
|
||||||
|
|
||||||
import aurweb.config
|
import aurweb.config
|
||||||
|
|
||||||
|
@ -86,28 +84,3 @@ def get_translator_for_request(request: Request):
|
||||||
return translator.translate(message, lang)
|
return translator.translate(message, lang)
|
||||||
|
|
||||||
return translate
|
return translate
|
||||||
|
|
||||||
|
|
||||||
@pass_context
|
|
||||||
def tr(context: typing.Any, value: str):
|
|
||||||
""" A translation filter; example: {{ "Hello" | tr("de") }}. """
|
|
||||||
_ = get_translator_for_request(context.get("request"))
|
|
||||||
return _(value)
|
|
||||||
|
|
||||||
|
|
||||||
@pass_context
|
|
||||||
def tn(context: typing.Dict[str, typing.Any], count: int,
|
|
||||||
singular: str, plural: str) -> str:
|
|
||||||
""" A singular and plural translation filter.
|
|
||||||
|
|
||||||
Example:
|
|
||||||
{{ some_integer | tn("singular %d", "plural %d") }}
|
|
||||||
|
|
||||||
:param context: Response context
|
|
||||||
:param count: The number used to decide singular or plural state
|
|
||||||
:param singular: The singular translation
|
|
||||||
:param plural: The plural translation
|
|
||||||
:return: Translated string
|
|
||||||
"""
|
|
||||||
gettext = get_raw_translator_for_request(context.get("request"))
|
|
||||||
return gettext.ngettext(singular, plural, count)
|
|
||||||
|
|
|
@ -4,7 +4,7 @@ from fastapi import APIRouter, Request
|
||||||
from fastapi.responses import Response
|
from fastapi.responses import Response
|
||||||
from feedgen.feed import FeedGenerator
|
from feedgen.feed import FeedGenerator
|
||||||
|
|
||||||
from aurweb import db, util
|
from aurweb import db, filters
|
||||||
from aurweb.models import Package, PackageBase
|
from aurweb.models import Package, PackageBase
|
||||||
|
|
||||||
router = APIRouter()
|
router = APIRouter()
|
||||||
|
@ -39,8 +39,8 @@ def make_rss_feed(request: Request, packages: list,
|
||||||
entry.description(pkg.Description or str())
|
entry.description(pkg.Description or str())
|
||||||
|
|
||||||
attr = getattr(pkg.PackageBase, date_attr)
|
attr = getattr(pkg.PackageBase, date_attr)
|
||||||
dt = util.timestamp_to_datetime(attr)
|
dt = filters.timestamp_to_datetime(attr)
|
||||||
dt = util.as_timezone(dt, request.user.Timezone)
|
dt = filters.as_timezone(dt, request.user.Timezone)
|
||||||
entry.pubDate(dt.strftime("%Y-%m-%d %H:%M:%S%z"))
|
entry.pubDate(dt.strftime("%Y-%m-%d %H:%M:%S%z"))
|
||||||
|
|
||||||
entry.source(f"{base}")
|
entry.source(f"{base}")
|
||||||
|
|
|
@ -8,8 +8,9 @@ from sqlalchemy import and_, literal, orm
|
||||||
|
|
||||||
import aurweb.config as config
|
import aurweb.config as config
|
||||||
|
|
||||||
from aurweb import db, defaults, models, util
|
from aurweb import db, defaults, models
|
||||||
from aurweb.exceptions import RPCError
|
from aurweb.exceptions import RPCError
|
||||||
|
from aurweb.filters import number_format
|
||||||
from aurweb.packages.search import RPCSearch
|
from aurweb.packages.search import RPCSearch
|
||||||
|
|
||||||
TYPE_MAPPING = {
|
TYPE_MAPPING = {
|
||||||
|
@ -124,7 +125,7 @@ class RPC:
|
||||||
# Produce RPC API compatible Popularity: If zero, it's an integer
|
# Produce RPC API compatible Popularity: If zero, it's an integer
|
||||||
# 0, otherwise, it's formatted to the 6th decimal place.
|
# 0, otherwise, it's formatted to the 6th decimal place.
|
||||||
pop = package.Popularity
|
pop = package.Popularity
|
||||||
pop = 0 if not pop else float(util.number_format(pop, 6))
|
pop = 0 if not pop else float(number_format(pop, 6))
|
||||||
|
|
||||||
snapshot_uri = config.get("options", "snapshot_uri")
|
snapshot_uri = config.get("options", "snapshot_uri")
|
||||||
return {
|
return {
|
||||||
|
|
|
@ -31,7 +31,7 @@ from sqlalchemy import literal, orm
|
||||||
|
|
||||||
import aurweb.config
|
import aurweb.config
|
||||||
|
|
||||||
from aurweb import db, logging, models, util
|
from aurweb import db, filters, logging, models, util
|
||||||
from aurweb.benchmark import Benchmark
|
from aurweb.benchmark import Benchmark
|
||||||
from aurweb.models import Package, PackageBase, User
|
from aurweb.models import Package, PackageBase, User
|
||||||
|
|
||||||
|
@ -264,7 +264,7 @@ def _main():
|
||||||
with gzip.open(USERS, "wt") as f:
|
with gzip.open(USERS, "wt") as f:
|
||||||
f.writelines([f"{user.Username}\n" for i, user in enumerate(query)])
|
f.writelines([f"{user.Username}\n" for i, user in enumerate(query)])
|
||||||
|
|
||||||
seconds = util.number_format(bench.end(), 4)
|
seconds = filters.number_format(bench.end(), 4)
|
||||||
logger.info(f"Completed in {seconds} seconds.")
|
logger.info(f"Completed in {seconds} seconds.")
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -13,6 +13,7 @@ from sqlalchemy import and_, or_
|
||||||
|
|
||||||
import aurweb.config
|
import aurweb.config
|
||||||
import aurweb.db
|
import aurweb.db
|
||||||
|
import aurweb.filters
|
||||||
import aurweb.l10n
|
import aurweb.l10n
|
||||||
|
|
||||||
from aurweb import db, l10n, logging
|
from aurweb import db, l10n, logging
|
||||||
|
@ -160,7 +161,7 @@ class ServerErrorNotification(Notification):
|
||||||
|
|
||||||
def get_body(self, lang: str) -> str:
|
def get_body(self, lang: str) -> str:
|
||||||
""" A forcibly English email body. """
|
""" A forcibly English email body. """
|
||||||
dt = aurweb.util.timestamp_to_datetime(self._utc)
|
dt = aurweb.filters.timestamp_to_datetime(self._utc)
|
||||||
dts = dt.strftime("%Y-%m-%d %H:%M")
|
dts = dt.strftime("%Y-%m-%d %H:%M")
|
||||||
return (f"Traceback ID: {self._tb_id}\n"
|
return (f"Traceback ID: {self._tb_id}\n"
|
||||||
f"Location: {aur_location}\n"
|
f"Location: {aur_location}\n"
|
||||||
|
|
|
@ -1,23 +1,20 @@
|
||||||
import copy
|
import copy
|
||||||
import functools
|
import functools
|
||||||
import math
|
|
||||||
import os
|
import os
|
||||||
import zoneinfo
|
import zoneinfo
|
||||||
|
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
from http import HTTPStatus
|
from http import HTTPStatus
|
||||||
from typing import Callable
|
from typing import Callable
|
||||||
from urllib.parse import quote_plus
|
|
||||||
|
|
||||||
import jinja2
|
import jinja2
|
||||||
|
|
||||||
from fastapi import Request
|
from fastapi import Request
|
||||||
from fastapi.responses import HTMLResponse
|
from fastapi.responses import HTMLResponse
|
||||||
|
|
||||||
import aurweb.auth.creds
|
|
||||||
import aurweb.config
|
import aurweb.config
|
||||||
|
|
||||||
from aurweb import captcha, cookies, l10n, time, util
|
from aurweb import cookies, l10n, time
|
||||||
|
|
||||||
# Prepare jinja2 objects.
|
# Prepare jinja2 objects.
|
||||||
_loader = jinja2.FileSystemLoader(os.path.join(
|
_loader = jinja2.FileSystemLoader(os.path.join(
|
||||||
|
@ -25,27 +22,6 @@ _loader = jinja2.FileSystemLoader(os.path.join(
|
||||||
_env = jinja2.Environment(loader=_loader, autoescape=True,
|
_env = jinja2.Environment(loader=_loader, autoescape=True,
|
||||||
extensions=["jinja2.ext.i18n"])
|
extensions=["jinja2.ext.i18n"])
|
||||||
|
|
||||||
# Add t{r,n} translation filters.
|
|
||||||
_env.filters["tr"] = l10n.tr
|
|
||||||
_env.filters["tn"] = l10n.tn
|
|
||||||
|
|
||||||
# Utility filters.
|
|
||||||
_env.filters["dt"] = util.timestamp_to_datetime
|
|
||||||
_env.filters["as_timezone"] = util.as_timezone
|
|
||||||
_env.filters["extend_query"] = util.extend_query
|
|
||||||
_env.filters["urlencode"] = util.to_qs
|
|
||||||
_env.filters["quote_plus"] = quote_plus
|
|
||||||
_env.filters["get_vote"] = util.get_vote
|
|
||||||
_env.filters["number_format"] = util.number_format
|
|
||||||
_env.filters["ceil"] = math.ceil
|
|
||||||
|
|
||||||
# Add captcha filters.
|
|
||||||
_env.filters["captcha_salt"] = captcha.captcha_salt_filter
|
|
||||||
_env.filters["captcha_cmdline"] = captcha.captcha_cmdline_filter
|
|
||||||
|
|
||||||
# Add account utility filters.
|
|
||||||
_env.filters["account_url"] = util.account_url
|
|
||||||
|
|
||||||
|
|
||||||
def register_filter(name: str) -> Callable:
|
def register_filter(name: str) -> Callable:
|
||||||
""" A decorator that can be used to register a filter.
|
""" A decorator that can be used to register a filter.
|
||||||
|
@ -65,8 +41,6 @@ def register_filter(name: str) -> Callable:
|
||||||
@functools.wraps(func)
|
@functools.wraps(func)
|
||||||
def wrapper(*args, **kwargs):
|
def wrapper(*args, **kwargs):
|
||||||
return func(*args, **kwargs)
|
return func(*args, **kwargs)
|
||||||
if name in _env.filters:
|
|
||||||
raise KeyError(f"Jinja already has a filter named '{name}'")
|
|
||||||
_env.filters[name] = wrapper
|
_env.filters[name] = wrapper
|
||||||
return wrapper
|
return wrapper
|
||||||
return decorator
|
return decorator
|
||||||
|
@ -88,6 +62,7 @@ def register_function(name: str) -> Callable:
|
||||||
|
|
||||||
def make_context(request: Request, title: str, next: str = None):
|
def make_context(request: Request, title: str, next: str = None):
|
||||||
""" Create a context for a jinja2 TemplateResponse. """
|
""" Create a context for a jinja2 TemplateResponse. """
|
||||||
|
import aurweb.auth.creds
|
||||||
|
|
||||||
commit_url = aurweb.config.get_with_fallback("devel", "commit_url", None)
|
commit_url = aurweb.config.get_with_fallback("devel", "commit_url", None)
|
||||||
commit_hash = aurweb.config.get_with_fallback("devel", "commit_hash", None)
|
commit_hash = aurweb.config.get_with_fallback("devel", "commit_hash", None)
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
import base64
|
import base64
|
||||||
import copy
|
|
||||||
import math
|
import math
|
||||||
import re
|
import re
|
||||||
import secrets
|
import secrets
|
||||||
|
@ -8,16 +7,14 @@ import string
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
from distutils.util import strtobool as _strtobool
|
from distutils.util import strtobool as _strtobool
|
||||||
from http import HTTPStatus
|
from http import HTTPStatus
|
||||||
from typing import Any, Callable, Dict, Iterable, Tuple
|
from typing import Callable, Iterable, Tuple
|
||||||
from urllib.parse import urlencode, urlparse
|
from urllib.parse import urlparse
|
||||||
from zoneinfo import ZoneInfo
|
|
||||||
|
|
||||||
import fastapi
|
import fastapi
|
||||||
import pygit2
|
import pygit2
|
||||||
|
|
||||||
from email_validator import EmailNotValidError, EmailUndeliverableError, validate_email
|
from email_validator import EmailNotValidError, EmailUndeliverableError, validate_email
|
||||||
from fastapi.responses import JSONResponse
|
from fastapi.responses import JSONResponse
|
||||||
from jinja2 import pass_context
|
|
||||||
|
|
||||||
import aurweb.config
|
import aurweb.config
|
||||||
|
|
||||||
|
@ -107,43 +104,6 @@ def valid_ssh_pubkey(pk):
|
||||||
return base64.b64encode(base64.b64decode(tokens[1])).decode() == tokens[1]
|
return base64.b64encode(base64.b64decode(tokens[1])).decode() == tokens[1]
|
||||||
|
|
||||||
|
|
||||||
@pass_context
|
|
||||||
def account_url(context: Dict[str, Any],
|
|
||||||
user: "aurweb.models.user.User") -> str:
|
|
||||||
base = aurweb.config.get("options", "aur_location")
|
|
||||||
return f"{base}/account/{user.Username}"
|
|
||||||
|
|
||||||
|
|
||||||
def timestamp_to_datetime(timestamp: int):
|
|
||||||
return datetime.utcfromtimestamp(int(timestamp))
|
|
||||||
|
|
||||||
|
|
||||||
def as_timezone(dt: datetime, timezone: str):
|
|
||||||
return dt.astimezone(tz=ZoneInfo(timezone))
|
|
||||||
|
|
||||||
|
|
||||||
def extend_query(query: Dict[str, Any], *additions) -> Dict[str, Any]:
|
|
||||||
""" Add additional key value pairs to query. """
|
|
||||||
q = copy.copy(query)
|
|
||||||
for k, v in list(additions):
|
|
||||||
q[k] = v
|
|
||||||
return q
|
|
||||||
|
|
||||||
|
|
||||||
def to_qs(query: Dict[str, Any]) -> str:
|
|
||||||
return urlencode(query, doseq=True)
|
|
||||||
|
|
||||||
|
|
||||||
def get_vote(voteinfo, request: fastapi.Request):
|
|
||||||
from aurweb.models import TUVote
|
|
||||||
return voteinfo.tu_votes.filter(TUVote.User == request.user).first()
|
|
||||||
|
|
||||||
|
|
||||||
def number_format(value: float, places: int):
|
|
||||||
""" A converter function similar to PHP's number_format. """
|
|
||||||
return f"{value:.{places}f}"
|
|
||||||
|
|
||||||
|
|
||||||
def jsonify(obj):
|
def jsonify(obj):
|
||||||
""" Perform a conversion on obj if it's needed. """
|
""" Perform a conversion on obj if it's needed. """
|
||||||
if isinstance(obj, datetime):
|
if isinstance(obj, datetime):
|
||||||
|
|
36
test/test_filters.py
Normal file
36
test/test_filters.py
Normal file
|
@ -0,0 +1,36 @@
|
||||||
|
from datetime import datetime
|
||||||
|
from zoneinfo import ZoneInfo
|
||||||
|
|
||||||
|
from aurweb import filters
|
||||||
|
|
||||||
|
|
||||||
|
def test_timestamp_to_datetime():
|
||||||
|
ts = datetime.utcnow().timestamp()
|
||||||
|
dt = datetime.utcfromtimestamp(int(ts))
|
||||||
|
assert filters.timestamp_to_datetime(ts) == dt
|
||||||
|
|
||||||
|
|
||||||
|
def test_as_timezone():
|
||||||
|
ts = datetime.utcnow().timestamp()
|
||||||
|
dt = filters.timestamp_to_datetime(ts)
|
||||||
|
assert filters.as_timezone(dt, "UTC") == dt.astimezone(tz=ZoneInfo("UTC"))
|
||||||
|
|
||||||
|
|
||||||
|
def test_number_format():
|
||||||
|
assert filters.number_format(0.222, 2) == "0.22"
|
||||||
|
assert filters.number_format(0.226, 2) == "0.23"
|
||||||
|
|
||||||
|
|
||||||
|
def test_extend_query():
|
||||||
|
""" Test extension of a query via extend_query. """
|
||||||
|
query = {"a": "b"}
|
||||||
|
extended = filters.extend_query(query, ("a", "c"), ("b", "d"))
|
||||||
|
assert extended.get("a") == "c"
|
||||||
|
assert extended.get("b") == "d"
|
||||||
|
|
||||||
|
|
||||||
|
def test_to_qs():
|
||||||
|
""" Test conversion from a query dictionary to a query string. """
|
||||||
|
query = {"a": "b", "c": [1, 2, 3]}
|
||||||
|
qs = filters.to_qs(query)
|
||||||
|
assert qs == "a=b&c=1&c=2&c=3"
|
|
@ -1,5 +1,5 @@
|
||||||
""" Test our l10n module. """
|
""" Test our l10n module. """
|
||||||
from aurweb import l10n
|
from aurweb import filters, l10n
|
||||||
from aurweb.testing.requests import Request
|
from aurweb.testing.requests import Request
|
||||||
|
|
||||||
|
|
||||||
|
@ -43,8 +43,10 @@ def test_tn_filter():
|
||||||
request.cookies["AURLANG"] = "en"
|
request.cookies["AURLANG"] = "en"
|
||||||
context = {"language": "en", "request": request}
|
context = {"language": "en", "request": request}
|
||||||
|
|
||||||
translated = l10n.tn(context, 1, "%d package found.", "%d packages found.")
|
translated = filters.tn(context, 1, "%d package found.",
|
||||||
|
"%d packages found.")
|
||||||
assert translated == "%d package found."
|
assert translated == "%d package found."
|
||||||
|
|
||||||
translated = l10n.tn(context, 2, "%d package found.", "%d packages found.")
|
translated = filters.tn(context, 2, "%d package found.",
|
||||||
|
"%d packages found.")
|
||||||
assert translated == "%d packages found."
|
assert translated == "%d packages found."
|
||||||
|
|
|
@ -8,6 +8,8 @@ import pytest
|
||||||
import aurweb.filters # noqa: F401
|
import aurweb.filters # noqa: F401
|
||||||
|
|
||||||
from aurweb import config, db, templates
|
from aurweb import config, db, templates
|
||||||
|
from aurweb.filters import as_timezone, number_format
|
||||||
|
from aurweb.filters import timestamp_to_datetime as to_dt
|
||||||
from aurweb.models import Package, PackageBase, User
|
from aurweb.models import Package, PackageBase, User
|
||||||
from aurweb.models.account_type import USER_ID
|
from aurweb.models.account_type import USER_ID
|
||||||
from aurweb.models.license import License
|
from aurweb.models.license import License
|
||||||
|
@ -17,8 +19,6 @@ from aurweb.models.relation_type import PROVIDES_ID, REPLACES_ID
|
||||||
from aurweb.templates import base_template, make_context, register_filter, register_function
|
from aurweb.templates import base_template, make_context, register_filter, register_function
|
||||||
from aurweb.testing.html import parse_root
|
from aurweb.testing.html import parse_root
|
||||||
from aurweb.testing.requests import Request
|
from aurweb.testing.requests import Request
|
||||||
from aurweb.util import as_timezone, number_format
|
|
||||||
from aurweb.util import timestamp_to_datetime as to_dt
|
|
||||||
|
|
||||||
GIT_CLONE_URI_ANON = "anon_%s"
|
GIT_CLONE_URI_ANON = "anon_%s"
|
||||||
GIT_CLONE_URI_PRIV = "priv_%s"
|
GIT_CLONE_URI_PRIV = "priv_%s"
|
||||||
|
@ -79,15 +79,6 @@ def create_license(pkg: Package, license_name: str) -> PackageLicense:
|
||||||
return pkglic
|
return pkglic
|
||||||
|
|
||||||
|
|
||||||
def test_register_filter_exists_key_error():
|
|
||||||
""" Most instances of register_filter are tested through module
|
|
||||||
imports or template renders, so we only test failures here. """
|
|
||||||
with pytest.raises(KeyError):
|
|
||||||
@register_filter("func")
|
|
||||||
def some_func():
|
|
||||||
pass
|
|
||||||
|
|
||||||
|
|
||||||
def test_register_function_exists_key_error():
|
def test_register_function_exists_key_error():
|
||||||
""" Most instances of register_filter are tested through module
|
""" Most instances of register_filter are tested through module
|
||||||
imports or template renders, so we only test failures here. """
|
imports or template renders, so we only test failures here. """
|
||||||
|
|
|
@ -10,7 +10,7 @@ import pytest
|
||||||
|
|
||||||
from fastapi.testclient import TestClient
|
from fastapi.testclient import TestClient
|
||||||
|
|
||||||
from aurweb import config, db, util
|
from aurweb import config, db, filters
|
||||||
from aurweb.models.account_type import DEVELOPER_ID, AccountType
|
from aurweb.models.account_type import DEVELOPER_ID, AccountType
|
||||||
from aurweb.models.tu_vote import TUVote
|
from aurweb.models.tu_vote import TUVote
|
||||||
from aurweb.models.tu_voteinfo import TUVoteInfo
|
from aurweb.models.tu_voteinfo import TUVoteInfo
|
||||||
|
@ -130,7 +130,7 @@ def test_tu_index_guest(client):
|
||||||
response = request.get("/tu", allow_redirects=False, headers=headers)
|
response = request.get("/tu", allow_redirects=False, headers=headers)
|
||||||
assert response.status_code == int(HTTPStatus.SEE_OTHER)
|
assert response.status_code == int(HTTPStatus.SEE_OTHER)
|
||||||
|
|
||||||
params = util.urlencode({"next": "/tu"})
|
params = filters.urlencode({"next": "/tu"})
|
||||||
assert response.headers.get("location") == f"/login?{params}"
|
assert response.headers.get("location") == f"/login?{params}"
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,8 +1,6 @@
|
||||||
import json
|
import json
|
||||||
|
|
||||||
from datetime import datetime
|
|
||||||
from http import HTTPStatus
|
from http import HTTPStatus
|
||||||
from zoneinfo import ZoneInfo
|
|
||||||
|
|
||||||
import fastapi
|
import fastapi
|
||||||
import pytest
|
import pytest
|
||||||
|
@ -13,38 +11,6 @@ from aurweb import filters, util
|
||||||
from aurweb.testing.requests import Request
|
from aurweb.testing.requests import Request
|
||||||
|
|
||||||
|
|
||||||
def test_timestamp_to_datetime():
|
|
||||||
ts = datetime.utcnow().timestamp()
|
|
||||||
dt = datetime.utcfromtimestamp(int(ts))
|
|
||||||
assert util.timestamp_to_datetime(ts) == dt
|
|
||||||
|
|
||||||
|
|
||||||
def test_as_timezone():
|
|
||||||
ts = datetime.utcnow().timestamp()
|
|
||||||
dt = util.timestamp_to_datetime(ts)
|
|
||||||
assert util.as_timezone(dt, "UTC") == dt.astimezone(tz=ZoneInfo("UTC"))
|
|
||||||
|
|
||||||
|
|
||||||
def test_number_format():
|
|
||||||
assert util.number_format(0.222, 2) == "0.22"
|
|
||||||
assert util.number_format(0.226, 2) == "0.23"
|
|
||||||
|
|
||||||
|
|
||||||
def test_extend_query():
|
|
||||||
""" Test extension of a query via extend_query. """
|
|
||||||
query = {"a": "b"}
|
|
||||||
extended = util.extend_query(query, ("a", "c"), ("b", "d"))
|
|
||||||
assert extended.get("a") == "c"
|
|
||||||
assert extended.get("b") == "d"
|
|
||||||
|
|
||||||
|
|
||||||
def test_to_qs():
|
|
||||||
""" Test conversion from a query dictionary to a query string. """
|
|
||||||
query = {"a": "b", "c": [1, 2, 3]}
|
|
||||||
qs = util.to_qs(query)
|
|
||||||
assert qs == "a=b&c=1&c=2&c=3"
|
|
||||||
|
|
||||||
|
|
||||||
def test_round():
|
def test_round():
|
||||||
assert filters.do_round(1.3) == 1
|
assert filters.do_round(1.3) == 1
|
||||||
assert filters.do_round(1.5) == 2
|
assert filters.do_round(1.5) == 2
|
||||||
|
|
Loading…
Add table
Reference in a new issue